spectrogrism

Generic utilities for modeling grism-based spectrograph.

Configuration(adict) A OrderedDict-derived configuration.
OptConfig(adict) Optical configuration.
SimConfig(adict) Simulation configuration.
Spectrum(wavelengths, fluxes[, name]) A wavelength-indexed pandas.Series.
PointSource(coords[, spectrum]) A Spectrum associated to a complex 2D-position or direction.
DetectorPositions(wavelengths, coordinates) A container for complex 2D-positions on the detector.
Material(name) Optical material.
Lens(gamma[, gdist, cdist]) Convert a 2D-position into a 2D-position.
CameraOrCollimator(flength[, gdist, cdist]) An optical element converting to and fro directions and positions.
Collimator(config) Convert a 2D-position (in the focal plane) into a 2D-direction.
Camera(config) Convert a 2D-direction into a 2D-position (in the detector plane).
Telescope(config) All-reflective telescope (no chromatic distortions).
Prism(angle, material[, tilts]) A triangular transmissive prism.
Grating(rho, material[, blaze]) A transmissive grating.
Grism(config) A Prism and a Grating on the exit surface.
Detector(config) A simple translated and rotated detector.
Spectrograph(config[, telescope]) A collimated spectrograph.

Inheritance diagram of spectrogrism.spectrogrism

spectrogrism.spectrogrism.RAD2DEG = 57.29577951308232

Convert from radians to degrees

spectrogrism.spectrogrism.RAD2MIN = 3437.746770784939

Convert from radians to arc minutes

spectrogrism.spectrogrism.RAD2SEC = 206264.80624709633

Convert from radians to arc seconds

class spectrogrism.spectrogrism.Configuration(adict)[source]

A OrderedDict-derived configuration.

override(adict) Override configuration from dictionary adict.
save(yamlname) Save configuration to YAML file yamlname.
load(yamlname) Load configuration from YAML file yamlname.

Initialize from dictionary adict.

conftype = 'Configuration'

Configuration type

override(adict)[source]

Override configuration from dictionary adict.

save(yamlname)[source]

Save configuration to YAML file yamlname.

classmethod load(yamlname)[source]

Load configuration from YAML file yamlname.

read_coeffs(name, start=0)[source]

Read keys ‘name{i}’ and return list [name0, name1, ...].

class spectrogrism.spectrogrism.OptConfig(adict)[source]

Optical configuration.

Initialize from dictionary adict.

conftype = 'Optical configuration'
wref
class spectrogrism.spectrogrism.SimConfig(adict)[source]

Simulation configuration.

get_wavelengths(optcfg) Simulated wavelengths.
get_coordinates() Simulated input complex coordinates [ x + 1j*y ].

Initialize from dictionary adict.

conftype = 'Simulation configuration'
get_wavelengths(optcfg)[source]

Simulated wavelengths.

get_coordinates()[source]

Simulated input complex coordinates [ x + 1j*y ].

class spectrogrism.spectrogrism.Spectrum(wavelengths, fluxes, name='spectrum')[source]

A wavelength-indexed pandas.Series.

Initialize from wavelength and flux arrays.

Parameters:
  • wavelengths (list) – strictly increasing input wavelengths [m]
  • fluxes (list) – input fluxes [arbitrary units]
  • name (str) – optional spectrum name (e.g. “Grism transmission”)
wavelengths

Wavelength array.

fluxes

Fluxes array.

classmethod default(wavelengths=[1e-06], name='')[source]

A default constant-flux spectrum.

Parameters:
  • wavelengths (list) – wavelength vector [m]
  • name (str) – optional name
Returns:

constant-flux spectrum

Return type:

Spectrum

class spectrogrism.spectrogrism.PointSource(coords, spectrum=None, **kwargs)[source]

A Spectrum associated to a complex 2D-position or direction.

Initialize from position/direction and spectrum.

Parameters:
  • coords (complex) – single source (complex) coordinates
  • spectrum (Spectrum) – source spectrum (default to standard spectrum)
  • kwargs – propagated to Spectrum.default() constructor
coords = None

2D-position/direction

spectrum = None

Spectrum

class spectrogrism.spectrogrism.DetectorPositions(wavelengths, coordinates, spectrograph=None, name='default')[source]

A container for complex 2D-positions on the detector.

A pandas.Panel-derived container for (complex) positions in the detector plane:

  • items are observational modes (dispersion orders or photometric bands)
  • major axis is wavelength (shared among all modes)
  • minor axis is input complex coordinates (shared among all modes)

For each mode, the corresponding pandas.DataFrame is therefore organized the following way:

          zin_1     zin_2  ...     zin_N
lbda1  zout_1_1  zout_2_1  ...  zout_N_1
lbda2  zout_1_2  zout_2_2  ...  zout_N_2
...
lbdaM  zout_1_M  zout_2_M  ...  zout_N_M
  • self.modes returns the available observing modes;
  • df = self.panel[mode] is the dataframe corresponding to a given observing mode;
  • self.wavelengths returns wavelength array [lbdas];
  • self.coordinates returns (complex) input coordinate array [zins];
  • df[zin] returns a wavelength-indexed pandas.Series of complex detector positions.

Warning

Indexing by float is not precisely a good idea... Float indices (wavelengths and input coordinates) are therefore rounded first with a sufficient precision (e.g. nm for wavelengths).

Todo

do not use complex coordinates as column name (this is not natively supported in Pandas, nor a good idea). Store input coordinates in an associated pandas.Series, and use series index as column names.

add_mode(mode, dataframe) Add dataframe as observational mode to current panel.
plot([ax, coords, modes, blaze, subsampling]) Plot spectra on detector plane.
check_alignment(other) Check compatibility in wavelengths and positions with other instance.
compute_offset(other[, mode]) Compute (complex) position offsets to other instance.
compute_rms(other[, mode]) Compute total RMS distance to other instance.

Initialize container from spectrograph and wavelength array.

Parameters:
  • wavelengths (list) – input wavelengths [m]
  • coordinates (list) – input complex coordinates
  • spectrograph (Spectrograph) – associated spectrograph (if any)
  • name (str) – informative label
digits = 12
markers = {0: 'D', 1: 'o', 2: 's', 'H': 'o', 'K': 's', 'J': 'D', -1: '.'}
spectrograph = None

Associated spectrograph

name = None

Name

modes

Observational mode list.

coordinates

Input source (complex) coordinate array.

wavelengths

Wavelength array.

add_mode(mode, dataframe)[source]

Add dataframe as observational mode to current panel.

plot(ax=None, coords=None, modes=None, blaze=False, subsampling=1, **kwargs)[source]

Plot spectra on detector plane.

Parameters:
  • ax (matplotlib.pyplot.Axes) – pre-existing axes instance if any
  • coords (list) – selection of input coordinates to be plotted
  • modes (list) – selection of observing modes to be plotted
  • blaze (bool) – encode the blaze function in the marker size
  • subsampling (int) – sub-sample coordinates and wavelengths
  • kwargs – options propagated to matplotlib.pyplot.Axes.scatter()
Returns:

matplotlib.pyplot.Axes

check_alignment(other)[source]

Check compatibility in wavelengths and positions with other instance.

Parameters:other (DetectorPositions) – other instance to be compared to
Raises:IndexError – incompatible instance
compute_offset(other, mode=1)[source]

Compute (complex) position offsets to other instance.

Parameters:
  • other (DetectorPositions) – other instance to be compared to
  • mode – observing mode (dispersion order or photometric band)
Returns:

(complex) position offsets [m]

Return type:

pandas.DataFrame

Raises:

KeyError – requested mode cannot be found

Warning

self and other are supposed to be compatible (see test_compatibility()).

compute_rms(other, mode=1)[source]

Compute total RMS distance to other instance.

Parameters:
  • other (DetectorPositions) – other instance to be tested
  • mode – observing mode (dispersion order or photometric band)
Returns:

RMS offset [m]

Return type:

float

Raises:

KeyError – requested mode cannot be found

Warning

self and other are supposed to be compatible (see test_compatibility()).

class spectrogrism.spectrogrism.Material(name)[source]

Optical material.

The refractive index is described by its Sellmeier coefficients.

Reference: Sellmeier equation

index(wavelengths) Compute refractive index from Sellmeier expansion.

Initialize material from its name.

Parameters:name (str) – material name (should be in Material.materials)
Raises:KeyError – unknown material name
materials = {'SK5': [0.99146382, 0.495982121, 0.98739392, 0.00522730467, 0.0172733646, 98.3594579], 'F2': [1.34533359, 0.209073176, 0.93735716, 0.00997743871, 0.0470450767, 111.886764], 'FS': [0.6961663, 0.4079426, 0.8974794, 0.004679148, 0.01351206, 97.934], 'UBK7': [1.01237433, 0.258985218, 1.00021628, 0.00588328615, 0.0190239921, 104.079777], 'SF4': [1.61957826, 0.339493189, 1.02566931, 0.0125502104, 0.0533559822, 117.65222], 'SF57': [1.81651371, 0.428893641, 1.07186278, 0.0143704198, 0.0592801172, 121.419942], 'EPR': [0.512479, 0.838483, -0.388459, -0.0112765, 0.0263791, 557.682], 'BK7': [1.03961212, 0.231792344, 1.01046945, 0.00600069867, 0.0200179144, 103.560653], 'null': [0, 0, 0, 0, 0, 0], 'EPB': [0.406836, 1.03517, -0.140328, -0.0247382, 0.0261501, 798.366]}

Sellmeier coefficients [B1, B2, B3, C1, C2, C3] of known materials.

coeffs = None

Sellmeier coefficients [B1, B2, B3, C1, C2, C3]

name = None

Name of the material

index(wavelengths)[source]

Compute refractive index from Sellmeier expansion.

Sellmeier expansion for refractive index:

\[n(\lambda)^2 = 1 + \sum_{i}\frac{B_i\lambda^2}{\lambda^2-C_i}\]

with \(\lambda\) in microns.

Parameters:wavelengths (numpy.ndarray) – wavelengths [m]
Returns:refractive index
class spectrogrism.spectrogrism.Lens(gamma, gdist=None, cdist=None)[source]

Convert a 2D-position into a 2D-position.

Initialize the element from its optical parameters.

Parameters:
  • gamma (float) – transverse ‘grandissement’
  • gdist (D.GeometricDistortion) – geometric distortion
  • cdist (D.ChromaticDistortion) – chromatic distortion (lateral color)
gamma = None

Transverse ‘grandissement’

gdist = None

Geometric distortion

cdist = None

Chromatic distortion (lateral color)

forward(positions)[source]
backward(positions)[source]
class spectrogrism.spectrogrism.CameraOrCollimator(flength, gdist=None, cdist=None)[source]

An optical element converting to and fro directions and positions.

Initialize the element from its optical parameters.

Parameters:
  • flength (float) – focal length [m]
  • gdist (D.GeometricDistortion) – geometric distortion
  • cdist (D.ChromaticDistortion) – chromatic distortion (lateral color)
flength = None

Focal length [m]

gdist = None

Geometric distortion

cdist = None

Chromatic distortion (lateral color)

class spectrogrism.spectrogrism.Collimator(config)[source]

Convert a 2D-position (in the focal plane) into a 2D-direction.

forward(positions, wavelengths, gamma) Forward light propagation through the collimator.
backward(directions, wavelength, gamma) Backward light propagation through the collimator.

Initialize from optical configuration.

Parameters:config (OptConfig) – optical configuration
Raises:KeyError – missing configuration key
forward(positions, wavelengths, gamma)[source]

Forward light propagation through the collimator.

where:

  • \(z = x + iy\) is the complex position
  • D is the D.GeometricDistortion geometric distortion
  • L is the D.ChromaticDistortion lateral color
  • \(\gamma\) is the spectrograph magnification (fcam/fcoll)

The geometric distortion is therefore applied on the (flipped) positions.

backward(directions, wavelength, gamma)[source]

Backward light propagation through the collimator.

See Collimator.forward() for details.

class spectrogrism.spectrogrism.Camera(config)[source]

Convert a 2D-direction into a 2D-position (in the detector plane).

Note

the detector coordinate axes are flipped, so that sources remain in the same quadrant in the focal and detector planes.

forward(directions, wavelengths) Forward light propagation through the camera.
backward(positions, wavelength) Backward light propagation through the camera.

Initialize from optical configuration.

Parameters:config (OptConfig) – optical configuration
Raises:KeyError – missing configuration key
forward(directions, wavelengths)[source]

Forward light propagation through the camera.

where:

  • \(z = x + iy\) is the complex position
  • D is the D.GeometricDistortion geometric distortion
  • L is the D.ChromaticDistortion lateral color

The geometric distortion is therefore applied on the (input) directions.

backward(positions, wavelength)[source]

Backward light propagation through the camera.

See Camera.forward() for details.

class spectrogrism.spectrogrism.Telescope(config)[source]

All-reflective telescope (no chromatic distortions).

Convert a 2D-direction in the sky into a 2D-position in the focal plane.

Initialize from optical configuration.

Parameters:config (OptConfig) – optical configuration
Raises:KeyError – missing configuration key
class spectrogrism.spectrogrism.Prism(angle, material, tilts=[0, 0, 0])[source]

A triangular transmissive prism.

Note

  • The entry surface is roughly perpendicular (up to the tilt angles) to the optical axis Oz.
  • The apex (prism angle) is aligned with the x-axis
rotation(x, y, theta) 2D-rotation of position around origin with direct angle theta [rad].
rotation_x(xyz, theta) Rotation around x-axis.
rotation_y(xyz, theta) Rotation around y-axis.
rotation_z(xyz, theta) Rotation around z-axis.
refraction(xyz, n1, n2) Refraction law from medium 1 to medium 2, by plane interface \((Oxy)\).

Initialize grism from its optical parameters.

Parameters:
  • angle (float) – prism angle [rad]
  • material (Material) – prism material
  • tilts (3-list) – prism tilts (x, y, z) [rad]
angle = None

Prism angle [rad]

material = None

Prism material

tilts = None

Prism tilts (x, y, z) [rad]

tiltx

Expose prism x-tilt [rad], rotation around the prism apex/grating grooves.

tilty

Expose prism y-tilt [rad].

tiltz

Expose prism z-tilt [rad], rotation around the optical axis.

static rotation(x, y, theta)[source]

2D-rotation of position around origin with direct angle theta [rad].

classmethod rotation_x(xyz, theta)[source]

Rotation around x-axis.

classmethod rotation_y(xyz, theta)[source]

Rotation around y-axis.

classmethod rotation_z(xyz, theta)[source]

Rotation around z-axis.

static refraction(xyz, n1, n2)[source]

Refraction law from medium 1 to medium 2, by plane interface \((Oxy)\).

Parameters:
  • xyz (3-tuple) – input 3D-direction (from medium 1)
  • n1 (float) – Refractive index of medium 1
  • n2 (float) – Refractive index of medium 2
Returns:

output 3D-direction (to medium 2)

Return type:

3-tuple

class spectrogrism.spectrogrism.Grating(rho, material, blaze=0)[source]

A transmissive grating.

The grooves of the (transmission) grating are aligned along x.

forward(xyz, wavelengths[, order]) Forward light propagation through a grating.
backward(xyz, wavelength[, order]) Backward light propagation through a grating.

Initialize grating from its optical parameters.

Parameters:
  • rho (float) – grating groove density [lines/mm]
  • material (Material) – grating material
  • blaze (float) – grating blaze angle [rad]
rho = None

Grating groove density [lines/mm]

material = None

Grating material

blaze = None

Grating blaze angle [rad]

forward(xyz, wavelengths, order=1)[source]

Forward light propagation through a grating.

The propagation is done from material (n) to vacuum (1).

Parameters:
  • xyz (3-tuple) – input 3D-direction (x, y, z) [m]
  • wavelengths (numpy.ndarray) – wavelengths [m]
  • order (int) – dispersion order
Returns:

output 3D-direction (x’, y’, z’)

Return type:

3-tuple

backward(xyz, wavelength, order=1)[source]

Backward light propagation through a grating.

The propagation is done from vacuum (1) to material (n).

Parameters:
  • xyz (3-tuple) – output 3D-direction (x’, y’, z’) [m]
  • wavelength (float) – wavelength [m]
  • order (int) – dispersion order
Returns:

input 3D-direction (x, y, z)

Return type:

3-tuple

class spectrogrism.spectrogrism.Grism(config)[source]

A Prism and a Grating on the exit surface.

blaze_function(wavelengths[, order]) Blaze function.
direction2xyz(direction) Convert a 2D-direction into a 3D-direction (a unit vector).
xyz2direction(xyz) Convert a 3D-direction (a unit vector) into a 2D-direction.
forward(direction, wavelengths[, order]) Forward propagation through a grism (prism + grating).
backward(direction, wavelength[, order]) Backward propagation through a grism (prism + grating).
null_deviation([order]) Null-deviation wavelength (approximated) [m].

Initialize from optical configuration.

Parameters:config (OptConfig) – optical configuration
Raises:KeyError – missing configuration key
blaze_function(wavelengths, order=1)[source]

Blaze function.

In the normal configuration, the blaze function of a grism is given by

\[B = \frac{\sin^2\Theta}{\Theta^2}\]

with:

  • \(\rho \lambda \Theta = \pi \cos\gamma \times (n_g\sin i - \sin r)\), \(\gamma\) being the blaze angle and \(\rho\) the line density of the grating;
  • \(i = \alpha' - \gamma\) where \(n_g \sin\alpha' = n_p\sin A\) with \(n_p\) and \(n_g\) the refraction index of prism glass and grating resine respectively and \(A\) the grism angle
  • \(r = \beta - \gamma\) where \(\sin\beta = n_p\sin A - m\rho\lambda\) with \(m\) the diffraction order.
Parameters:
  • wavelengths (numpy.ndarray) – wavelengths [m]
  • order (int) – dispersion order
Returns:

blaze function (i.e. transmission at input wavelengths)

Return type:

numpy.ndarray

static direction2xyz(direction)[source]

Convert a 2D-direction into a 3D-direction (a unit vector).

Parameters:direction (complex) – 2D-direction
Returns:3D-direction
Type:3-tuple
static xyz2direction(xyz)[source]

Convert a 3D-direction (a unit vector) into a 2D-direction.

Parameters:xyz (3-tuple) – 3D-direction
Returns:2D-direction
Return type:complex
forward(direction, wavelengths, order=1)[source]

Forward propagation through a grism (prism + grating).

Parameters:
  • direction (complex) – 2D-direction [rad]
  • wavelengths (numpy.ndarray) – wavelengths [m]
  • order (int) – dispersion order
Returns:

2D-directions [rad]

Return type:

numpy.ndarray

backward(direction, wavelength, order=1)[source]

Backward propagation through a grism (prism + grating).

See Grism.forward() for parameters.

null_deviation(order=1)[source]

Null-deviation wavelength (approximated) [m].

This is the solution to:

\[m \rho \lambda = (n(\lambda) - 1) \sin(A)\]

where:

  • A: grism angle [rad]
  • \(\rho\): groove density [line/mm]
  • \(n(\lambda)\): prism refractive index
  • m: dispersion order
Parameters:order (int) – dispersion order
Returns:null deviation wavelength [m]
Raises:RuntimeError – if not converging
class spectrogrism.spectrogrism.Detector(config)[source]

A simple translated and rotated detector.

forward(positions) Forward propagation to detector.
backward(positions) Backward propagation from detector.

Initialize from optical configuration.

Parameters:config (OptConfig) – optical configuration
Raises:KeyError – missing configuration key
dx = None

X-offset [m]

dy = None

Y-offset [m]

angle = None

Rotation [rad]

pxsize = None

Pixel size [m]

dxdy

Expose complex offset dx + 1j*dy [m].

forward(positions)[source]

Forward propagation to detector.

backward(positions)[source]

Backward propagation from detector.

class spectrogrism.spectrogrism.Spectrograph(config, telescope=None)[source]

A collimated spectrograph.

A Collimator, a Grism in a collimated beam, a Camera and a Detector, plus an optional Telescope.

dispersion(wavelength[, order, eps]) Spectral dispersion (approximate) [m/m].
forward(source[, mode]) Forward light propagation from a focal-plane point source.
backward(position, wavelength[, mode]) Backward light propagation from a detector-plane 2D-position and wavelength.
test([waves, coords, mode, verbose]) Test forward and backward propagation in spectrograph.
predict_positions(simcfg, **kwargs) Simulate detector spectra from optical model.

Initialize spectrograph from optical configuration.

Parameters:
  • config (OptConfig) – optical configuration
  • telescope (Telescope) – input telescope if any
config = None

Optical configuration

telescope = None

Telescope

collimator = None

Collimator

grism = None

Grism

camera = None

Camera

detector = None

Detector

gamma

Spectrograph magnification \(f_{\mathrm{cam}}/f_{\mathrm{coll}}\).

dispersion(wavelength, order=1, eps=1e-06)[source]

Spectral dispersion (approximate) [m/m].

This is given by \(D(\lambda) = (\mathrm{d}y / \mathrm{d}\lambda)^{-1}\) with

\[y = f_{\mathrm{cam}}\tan\beta\]

and

\[\sin\beta = m \rho \lambda - n(\lambda) \sin(A).\]
Parameters:
  • wavelength (float) – wavelength [m]
  • order (int) – dispersion order
Returns:

spectral dispersion [m/m]

forward(source, mode=1)[source]

Forward light propagation from a focal-plane point source.

Parameters:
  • source (PointSource) – input source
  • mode – observing mode (dispersion order or photometric band)
Returns:

(complex) 2D-positions in detector plane

Return type:

numpy.ndarray

backward(position, wavelength, mode=1)[source]

Backward light propagation from a detector-plane 2D-position and wavelength.

Parameters:
  • position (complex) – 2D-position in the detector plane [m]
  • wavelength (float) – wavelength [m]
  • mode – observing mode (dispersion order or photometric band)
Returns:

2D-position in the focal plane [m]

Return type:

complex

test(waves=None, coords=(0.001+0.002j), mode=1, verbose=False)[source]

Test forward and backward propagation in spectrograph.

Parameters:
  • waves (list) – wavelength vector to be tested
  • position (complex) – input (complex) coordinates to be tested
  • mode – observing mode (dispersion order or photometric band)
  • verbose (bool) – verbose-mode
Returns:

boolean result of the forward/backward test

predict_positions(simcfg, **kwargs)[source]

Simulate detector spectra from optical model.

Parameters:
  • simcfg (SimConfig) – input simulation configuration
  • kwargs – configuration options (e.g. predicted modes)
Returns:

predicted positions [m]

Return type:

DetectorPositions

update(**kwargs)[source]

Update both optical configuration and structure parameters.

optimize(positions, simcfg, modes=None, optparams=['telescope_flength', 'collimator_flength', 'camera_flength'], tol=1e-06)[source]

scipy.optimize optical parameters to match target detector positions, according to simulation configuration.

Parameters:
  • positions (DetectorPositions) – target positions
  • simcfg (SimConfig) – simulation configuration
  • modes (list) – adjusted observing modes (default: simulated modes)
  • optparams (list) – optical parameters to be adjusted
  • tol (float) – optimization tolerance
Returns:

result from the optimization

Return type:

scipy.optimize.OptimizeResult

Raises:

KeyError – unknown optical parameter

adjust(positions, simcfg, modes=None, optparams=['telescope_flength', 'collimator_flength', 'camera_flength'], **options)[source]

iminuit adjustement of optical parameters to match target detector positions, according to simulation configuration.

Parameters:
  • positions (DetectorPositions) – target positions
  • simcfg (SimConfig) – simulation configuration
  • modes (list) – adjusted observing modes (default: simulated modes)
  • optparams (list) – optical parameters to be adjusted
  • options (dict) – iminuit additional options
Returns:

result from the optimization

Return type:

iminuit.Minuit

Raises:

KeyError – unknown optical parameter

spectrogrism.spectrogrism.is_spectred(mode)[source]

Is observational mode a spectroscopic (int-like) or photometric (str-like) mode?

spectrogrism.spectrogrism.str_mode(mode)[source]

String ‘Order #X’ or ‘Band Y’ from mode.

spectrogrism.spectrogrism.rect2pol(position)[source]

Convert complex position(s) \(x + jy\) into modulus \(r\) and phase \(\phi\).

Parameters:position (complex) – 2D-position(s) \(x + jy\)
Returns:(r, phi) [rad]
spectrogrism.spectrogrism.pol2rect(r, phi)[source]

Convert modulus \(r\) and phase \(\phi\) into complex position(s) \(x + jy = r\exp(j\phi)\).

Parameters:
  • r (float) – module(s)
  • phi (float) – phase(s) [rad]
Returns:

complex 2D-position(s)

spectrogrism.spectrogrism.dump_mpld3(fig, filename)[source]

Dump figure to mpld3 HTML-file.

spectrogrism.spectrogrism.dump_bokeh(fig, filename)[source]

Dump figure to bokeh HTML-file.

Warning

Bokeh-0.11 does not yet convert properly the figure.