spectrogrism

Generic utilities for modeling grism-based spectrograph.

Configuration([adict])

A OrderedDict-derived configuration.

OptConfig([adict])

Optical configuration.

SimConfig([adict])

Simulation configuration.

SourceXDA(wavelengths[, signal, zcoord, name])

A 1D xarray.DataArray.

DetectorPositionsXDA(wavelengths, coordinates)

A 2D xarray.DataArray.

DetectorPositions([wavelengths, …])

DEPRECATED DOCSTRING

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'

Configuration type

property wref

Central wavelength.

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'

Configuration type

get_wavelengths(optcfg)[source]

Simulated wavelengths.

get_coordinates()[source]

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

spectrogrism.spectrogrism.SourceXDA(wavelengths, signal=1, zcoord=0j, name=None)[source]

A 1D xarray.DataArray.

  • values: signal (float)

  • indices: wavelength (float)

  • attrs: zcoord (complex)

Parameters
  • wavelengths (list) – strictly increasing input wavelengths [m]

  • signal (list) – input signal [arbitrary units]

  • name (str) – optional spectrum name (e.g. “Grism transmission”)

spectrogrism.spectrogrism.str_SourceXDA(self)[source]

Return a SourceXDA string.

spectrogrism.spectrogrism.DetectorPositionsXDA(wavelengths, coordinates, zout=0)[source]

A 2D xarray.DataArray.

  • values: output coordinates (complex)

  • indices: wavelength (float) and coordinates (complex)

Parameters
  • wavelengths (list) – strictly increasing input wavelengths [m]

  • coordinates (list) – input complex coordinates [m]

  • zout (list) – output (wavelengths, zin) complex coordinates [m]

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

DEPRECATED DOCSTRING

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

  • 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, xda)

Add xda as observational mode to current panel.

plot([ax, coordinates, modes, blaze, …])

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 empty container from spectrograph and wavelength array.

Parameters
  • wavelengths (list) – input wavelengths [m]

  • coordinates (list) – input complex coordinates [m]

  • spectrograph (Spectrograph) – associated spectrograph (if any)

  • name (str) – informative label

mdict = {-1: 'D', 0: '.', 1: 'o', 2: 's', 'Y': 'D', 'J': 'o', 'H': 's'}
property modes

Observational mode array.

property coordinates

Input source (complex) coordinate array.

property wavelengths

Wavelength array.

add_mode(mode, xda)[source]

Add xda as observational mode to current panel.

plot(ax=None, coordinates=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

  • coordinates (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

plot_bokeh(p=None, coordinates=None, modes=None, blaze=False, subsampling=1, colorbar=False, **kwargs)[source]
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 = {'BK7': [1.03961212, 0.231792344, 1.01046945, 0.00600069867, 0.0200179144, 103.560653], 'EPB': [0.406836, 1.03517, -0.140328, -0.0247382, 0.0261501, 798.366], 'EPR': [0.512479, 0.838483, -0.388459, -0.0112765, 0.0263791, 557.682], '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], '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], 'SK5': [0.99146382, 0.495982121, 0.98739392, 0.00522730467, 0.0172733646, 98.3594579], 'UBK7': [1.01237433, 0.258985218, 1.00021628, 0.00588328615, 0.0190239921, 104.079777], 'null': [0, 0, 0, 0, 0, 0]}

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

coeffs

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

name

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

Transverse ‘grandissement’

gdist

Geometric distortion

cdist

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

Focal length [m]

gdist

Geometric distortion

cdist

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

Prism angle [rad]

material

Prism material

tilts

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

property tiltx

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

property tilty

Expose prism y-tilt [rad].

property 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

Grating groove density [lines/mm]

material

Grating material

blaze

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

X-offset [m]

dy

Y-offset [m]

angle

Rotation [rad]

pxsize

Pixel size [m]

property 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, zcoord, 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

Optical configuration

telescope

Telescope

collimator

Collimator

grism

Grism

camera

Camera

detector

Detector

property 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 – 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, zcoord=0.001 + 0.002j, mode=1, verbose=False)[source]

Test forward and backward propagation in spectrograph.

Parameters
  • waves (list) – wavelength vector to be tested

  • zcoord (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.