Commit 031ff30e authored by xin's avatar xin
Browse files

init

parents
File added
'''
Author: zx
Date: 2021-04-08 13:49:35
LastEditTime: 2022-05-20 08:45:03
LastEditors: xin zhangxinbjfu@gmail.com
Description: In User Settings Edit
FilePath: /undefined/Users/zhangxin/Work/SlitlessSim/sls_lit_demo/SpecDisperser/SpecDisperser.py
'''
from astropy.table import Table
import astropy.constants as cons
import collections
from collections import OrderedDict
from scipy import interpolate
from astropy import units as u
# from numpy import *
import numpy as np
from pylab import *
import galsim
import sys
import os
def rotate90(array_orig=None, xc=0, yc=0, isClockwise=0):
if array_orig is None:
return
l1 = array_orig.shape[0]
l2 = array_orig.shape[1]
if xc < 0 or xc > l2 - 1 or yc < 0 or yc > l1 - 1:
return
n_xc = xc
n_yc = yc
array_final = np.zeros_like(array_orig.T)
if isClockwise == 1:
for i in np.arange(l2):
array_final[i] = array_orig[:, l2 - i - 1]
n_xc = yc
n_yc = l2 - 1 - xc
else:
for i in np.arange(l2):
array_final[i] = array_orig[::-1, i]
n_xc = l1 - 1 - yc
n_yc = xc
return array_final, n_xc, n_yc
class SpecDisperser(object):
def __init__(self, orig_img=None, xcenter=0, ycenter=0, origin=[100, 100], tar_spec=None, band_start=2550,
band_end=10000, isAlongY=0, conf='../param/CONF/csst.conf', gid=0):
"""
orig_img: normal image,galsim image
xcenter, ycenter: the center of galaxy in orig_img
origin : [int, int]
`origin` defines the lower left pixel index (y,x) of the `direct`
cutout from a larger detector-frame image
tar_spec: galsim.SED
"""
# self.img_x = orig_img.shape[1]
# self.img_y = orig_img.shape[0]
self.thumb_img = np.abs(orig_img.array)
self.thumb_x = orig_img.center.x
self.thumb_y = orig_img.center.y
self.img_sh = orig_img.array.shape
self.id = gid
self.xcenter = xcenter
self.ycenter = ycenter
self.isAlongY = isAlongY
if self.isAlongY == 1:
self.thumb_img, self.thumb_x, self.thumb_y = rotate90(array_orig=self.thumb_img, xc=orig_img.center.x,
yc=orig_img.center.y, isClockwise=1)
self.img_sh = orig_img.array.T.shape
self.xcenter = ycenter
self.ycenter = xcenter
self.origin = origin
self.band_start = band_start
self.band_end = band_end
self.spec = tar_spec
self.beam_flux = OrderedDict()
self.grating_conf = aXeConf(conf)
self.grating_conf.get_beams()
self.grating_conf_file = conf
def compute_spec_orders(self):
all_orders = OrderedDict()
beam_names = self.grating_conf.beams
for beam in beam_names:
all_orders[beam] = self.compute_spec(beam)
return all_orders
def compute_spec(self, beam):
from .disperse_c import interp
from .disperse_c import disperse
# from MockObject.disperse_c import disperse
dx = self.grating_conf.dxlam[beam]
xoff = 0
ytrace_beam, lam_beam = self.grating_conf.get_beam_trace(x=self.xcenter, y=self.ycenter, dx=(dx + xoff),
beam=beam)
### Account for pixel centering of the trace
yfrac_beam = ytrace_beam - floor(ytrace_beam)
ysens = lam_beam * 0
lam_index = argsort(lam_beam)
conf_sens = self.grating_conf.sens[beam]
lam_intep = np.linspace(self.band_start, self.band_end, int((self.band_end - self.band_start) / 0.5))
thri = interpolate.interp1d(conf_sens['WAVELENGTH'], conf_sens['SENSITIVITY'])
spci = interpolate.interp1d(self.spec['WAVELENGTH'], self.spec['FLUX'])
beam_thr = thri(lam_intep)
spec_sample = spci(lam_intep)
bean_thr_spec = beam_thr * spec_sample
ysensitivity = lam_beam * 0
ysensitivity[lam_index] = interp.interp_conserve_c(lam_beam[lam_index], lam_intep,
beam_thr * math.pi * 100 * 100 * 1e-7 / (
cons.h.value * cons.c.value / (
lam_intep * 1e-10)), integrate=0, left=0,
right=0)
ysens[lam_index] = interp.interp_conserve_c(lam_beam[lam_index], lam_intep, bean_thr_spec, integrate=1, left=0,
right=0)
sensitivity_beam = ysens
len_spec_x = len(dx)
len_spec_y = int(ceil(yfrac_beam[-1]) - floor(yfrac_beam[0]) + 1)
beam_sh = (self.img_sh[0] + len_spec_y, self.img_sh[1] + len_spec_x)
modelf = zeros(product(beam_sh), dtype=float)
model = modelf.reshape(beam_sh)
idx = np.arange(modelf.size, dtype=int64).reshape(beam_sh)
x0 = array((self.thumb_y, self.thumb_x), dtype=int64)
dxpix = dx - dx[0] + x0[1]
dyc = cast[int](ytrace_beam)
dypix = dyc - dyc[0] + x0[0]
flat_index = idx[dypix, dxpix]
nonz = sensitivity_beam != 0
status = disperse.disperse_grism_object(self.thumb_img,
flat_index[nonz], yfrac_beam[nonz],
sensitivity_beam[nonz],
modelf, x0,
array(self.img_sh, dtype=int64),
array(beam_sh, dtype=int64))
model = modelf.reshape(beam_sh)
self.beam_flux[beam] = sum(modelf)
origin_in = zeros_like(self.origin)
dx0_in = dx[0]
dy0_in = dyc[0]
if self.isAlongY == 1:
model, tmx, tmy = rotate90(array_orig=model, isClockwise=0)
origin_in[0] = self.origin[0]
origin_in[1] = self.origin[1] - len_spec_y
dx0_in = -dyc[0]
dy0_in = dx[0]
else:
origin_in[0] = self.origin[0]
origin_in[1] = self.origin[1]
dx0_in = dx[0]
dy0_in = dyc[0]
originOut_x = origin_in[1] + dx0_in - 1
originOut_y = origin_in[0] + dy0_in - 1
return model, originOut_x, originOut_y, dxpix, dypix, lam_beam[lam_index],ysens[lam_index]
def writerSensitivityFile(self, conffile = '', beam = '', w = None, sens = None):
orders={'A':'1st','B':'0st','C':'2st'}
sens_file_name = conffile[0:-5]+'_sensitivity_'+ orders[beam] + '.fits'
if not os.path.exists(sens_file_name) == True:
senstivity_out = Table(array([w,sens]).T, names=('WAVELENGTH', 'SENSITIVITY'))
senstivity_out.write(sens_file_name, format='fits')
"""
Demonstrate aXe trace polynomials.
"""
class aXeConf():
def __init__(self, conf_file='WFC3.IR.G141.V2.5.conf'):
"""Read an aXe-compatible configuration file
Parameters
----------
conf_file: str
Filename of the configuration file to read
"""
if conf_file is not None:
self.conf = self.read_conf_file(conf_file)
self.conf_file = conf_file
self.count_beam_orders()
## Global XOFF/YOFF offsets
if 'XOFF' in self.conf.keys():
self.xoff = np.float(self.conf['XOFF'])
else:
self.xoff = 0.
if 'YOFF' in self.conf.keys():
self.yoff = np.float(self.conf['YOFF'])
else:
self.yoff = 0.
def read_conf_file(self, conf_file='WFC3.IR.G141.V2.5.conf'):
"""Read an aXe config file, convert floats and arrays
Parameters
----------
conf_file: str
Filename of the configuration file to read.
Parameters are stored in an OrderedDict in `self.conf`.
"""
from collections import OrderedDict
conf = OrderedDict()
lines = open(conf_file).readlines()
for line in lines:
## empty / commented lines
if (line.startswith('#')) | (line.strip() == '') | ('"' in line):
continue
## split the line, taking out ; and # comments
spl = line.split(';')[0].split('#')[0].split()
param = spl[0]
if len(spl) > 2:
value = np.cast[float](spl[1:])
else:
try:
value = float(spl[1])
except:
value = spl[1]
conf[param] = value
return conf
def count_beam_orders(self):
"""Get the maximum polynomial order in DYDX or DLDP for each beam
"""
self.orders = {}
for beam in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']:
order = 0
while 'DYDX_{0:s}_{1:d}'.format(beam, order) in self.conf.keys():
order += 1
while 'DLDP_{0:s}_{1:d}'.format(beam, order) in self.conf.keys():
order += 1
self.orders[beam] = order - 1
def get_beams(self):
"""Get beam parameters and read sensitivity curves
"""
import os
from collections import OrderedDict
from astropy.table import Table, Column
self.dxlam = OrderedDict()
self.nx = OrderedDict()
self.sens = OrderedDict()
self.beams = []
for beam in self.orders:
if self.orders[beam] > 0:
self.beams.append(beam)
self.dxlam[beam] = np.arange(self.conf['BEAM{0}'.format(beam)].min(),
self.conf['BEAM{0}'.format(beam)].max(), dtype=int)
self.nx[beam] = int(self.dxlam[beam].max() - self.dxlam[beam].min()) + 1
self.sens[beam] = Table.read(
'{0}/{1}'.format(os.path.dirname(self.conf_file), self.conf['SENSITIVITY_{0}'.format(beam)]))
# self.sens[beam].wave = np.cast[np.double](self.sens[beam]['WAVELENGTH'])
# self.sens[beam].sens = np.cast[np.double](self.sens[beam]['SENSITIVITY'])
### Need doubles for interpolating functions
for col in self.sens[beam].colnames:
data = np.cast[np.double](self.sens[beam][col])
self.sens[beam].remove_column(col)
self.sens[beam].add_column(Column(data=data, name=col))
self.beams.sort()
def field_dependent(self, xi, yi, coeffs):
"""aXe field-dependent coefficients
See the `aXe manual <http://axe.stsci.edu/axe/manual/html/node7.html#SECTION00721200000000000000>`_ for a description of how the field-dependent coefficients are specified.
Parameters
----------
xi, yi : float or array-like
Coordinate to evaluate the field dependent coefficients, where
`xi = x-REFX` and `yi = y-REFY`.
coeffs : array-like
Field-dependency coefficients
Returns
-------
a : float or array-like
Evaluated field-dependent coefficients
"""
## number of coefficients for a given polynomial order
## 1:1, 2:3, 3:6, 4:10, order:order*(order+1)/2
if isinstance(coeffs, float):
order = 1
else:
order = int(-1 + np.sqrt(1 + 8 * len(coeffs))) // 2
## Build polynomial terms array
## $a = a_0+a_1x_i+a_2y_i+a_3x_i^2+a_4x_iy_i+a_5yi^2+$ ...
xy = []
for p in range(order):
for px in range(p + 1):
# print 'x**%d y**%d' %(p-px, px)
xy.append(xi ** (p - px) * yi ** (px))
## Evaluate the polynomial, allowing for N-dimensional inputs
a = np.sum((np.array(xy).T * coeffs).T, axis=0)
return a
def evaluate_dp(self, dx, dydx):
"""Evalate arc length along the trace given trace polynomial coefficients
Parameters
----------
dx : array-like
x pixel to evaluate
dydx : array-like
Coefficients of the trace polynomial
Returns
-------
dp : array-like
Arc length along the trace at position `dx`.
For `dydx` polynomial orders 0, 1 or 2, integrate analytically.
Higher orders must be integrated numerically.
**Constant:**
.. math:: dp = dx
**Linear:**
.. math:: dp = \sqrt{1+\mathrm{DYDX}[1]}\cdot dx
**Quadratic:**
.. math:: u = \mathrm{DYDX}[1] + 2\ \mathrm{DYDX}[2]\cdot dx
.. math:: dp = (u \sqrt{1+u^2} + \mathrm{arcsinh}\ u) / (4\cdot \mathrm{DYDX}[2])
"""
## dp is the arc length along the trace
## $\lambda = dldp_0 + dldp_1 dp + dldp_2 dp^2$ ...
poly_order = len(dydx) - 1
if (poly_order == 2):
if np.abs(np.unique(dydx[2])).max() == 0:
poly_order = 1
if poly_order == 0: ## dy=0
dp = dx
elif poly_order == 1: ## constant dy/dx
dp = np.sqrt(1 + dydx[1] ** 2) * (dx)
elif poly_order == 2: ## quadratic trace
u0 = dydx[1] + 2 * dydx[2] * (0)
dp0 = (u0 * np.sqrt(1 + u0 ** 2) + np.arcsinh(u0)) / (4 * dydx[2])
u = dydx[1] + 2 * dydx[2] * (dx)
dp = (u * np.sqrt(1 + u ** 2) + np.arcsinh(u)) / (4 * dydx[2]) - dp0
else:
## high order shape, numerical integration along trace
## (this can be slow)
xmin = np.minimum((dx).min(), 0)
xmax = np.maximum((dx).max(), 0)
xfull = np.arange(xmin, xmax)
dyfull = 0
for i in range(1, poly_order):
dyfull += i * dydx[i] * (xfull - 0.5) ** (i - 1)
## Integrate from 0 to dx / -dx
dpfull = xfull * 0.
lt0 = xfull < 0
if lt0.sum() > 1:
dpfull[lt0] = np.cumsum(np.sqrt(1 + dyfull[lt0][::-1] ** 2))[::-1]
dpfull[lt0] *= -1
#
gt0 = xfull > 0
if gt0.sum() > 0:
dpfull[gt0] = np.cumsum(np.sqrt(1 + dyfull[gt0] ** 2))
dp = np.interp(dx, xfull, dpfull)
if dp[-1] == dp[-2]:
dp[-1] = dp[-2] + np.diff(dp)[-2]
return dp
def get_beam_trace(self, x=507, y=507, dx=0., beam='A'):
"""Get an aXe beam trace for an input reference pixel and list of output x pixels `dx`
Parameters
----------
x, y : float or array-like
Evaluate trace definition at detector coordinates `x` and `y`.
dx : float or array-like
Offset in x pixels from `(x,y)` where to compute trace offset and
effective wavelength
beam : str
Beam name (i.e., spectral order) to compute. By aXe convention,
`beam='A'` is the first order, 'B' is the zeroth order and
additional beams are the higher positive and negative orders.
Returns
-------
dy : float or array-like
Center of the trace in y pixels offset from `(x,y)` evaluated at
`dx`.
lam : float or array-like
Effective wavelength along the trace evaluated at `dx`.
"""
NORDER = self.orders[beam] + 1
xi, yi = x - self.xoff, y - self.yoff
xoff_beam = self.field_dependent(xi, yi, self.conf['XOFF_{0}'.format(beam)])
yoff_beam = self.field_dependent(xi, yi, self.conf['YOFF_{0}'.format(beam)])
## y offset of trace (DYDX)
dydx = np.zeros(NORDER) # 0 #+1.e-80
dydx = [0] * NORDER
for i in range(NORDER):
if 'DYDX_{0:s}_{1:d}'.format(beam, i) in self.conf.keys():
coeffs = self.conf['DYDX_{0:s}_{1:d}'.format(beam, i)]
dydx[i] = self.field_dependent(xi, yi, coeffs)
# $dy = dydx_0+dydx_1 dx+dydx_2 dx^2+$ ...
dy = yoff_beam
for i in range(NORDER):
dy += dydx[i] * (dx - xoff_beam) ** i
## wavelength solution
dldp = np.zeros(NORDER)
dldp = [0] * NORDER
for i in range(NORDER):
if 'DLDP_{0:s}_{1:d}'.format(beam, i) in self.conf.keys():
coeffs = self.conf['DLDP_{0:s}_{1:d}'.format(beam, i)]
dldp[i] = self.field_dependent(xi, yi, coeffs)
self.eval_input = {'x': x, 'y': y, 'beam': beam, 'dx': dx}
self.eval_output = {'xi': xi, 'yi': yi, 'dldp': dldp, 'dydx': dydx,
'xoff_beam': xoff_beam, 'yoff_beam': yoff_beam,
'dy': dy}
dp = self.evaluate_dp(dx - xoff_beam, dydx)
# ## dp is the arc length along the trace
# ## $\lambda = dldp_0 + dldp_1 dp + dldp_2 dp^2$ ...
# if self.conf['DYDX_ORDER_%s' %(beam)] == 0: ## dy=0
# dp = dx-xoff_beam
# elif self.conf['DYDX_ORDER_%s' %(beam)] == 1: ## constant dy/dx
# dp = np.sqrt(1+dydx[1]**2)*(dx-xoff_beam)
# elif self.conf['DYDX_ORDER_%s' %(beam)] == 2: ## quadratic trace
# u0 = dydx[1]+2*dydx[2]*(0)
# dp0 = (u0*np.sqrt(1+u0**2)+np.arcsinh(u0))/(4*dydx[2])
# u = dydx[1]+2*dydx[2]*(dx-xoff_beam)
# dp = (u*np.sqrt(1+u**2)+np.arcsinh(u))/(4*dydx[2])-dp0
# else:
# ## high order shape, numerical integration along trace
# ## (this can be slow)
# xmin = np.minimum((dx-xoff_beam).min(), 0)
# xmax = np.maximum((dx-xoff_beam).max(), 0)
# xfull = np.arange(xmin, xmax)
# dyfull = 0
# for i in range(1, NORDER):
# dyfull += i*dydx[i]*(xfull-0.5)**(i-1)
#
# ## Integrate from 0 to dx / -dx
# dpfull = xfull*0.
# lt0 = xfull <= 0
# if lt0.sum() > 1:
# dpfull[lt0] = np.cumsum(np.sqrt(1+dyfull[lt0][::-1]**2))[::-1]
# dpfull[lt0] *= -1
# #
# gt0 = xfull >= 0
# if gt0.sum() > 0:
# dpfull[gt0] = np.cumsum(np.sqrt(1+dyfull[gt0]**2))
#
# dp = np.interp(dx-xoff_beam, xfull, dpfull)
## Evaluate dldp
lam = dp * 0.
for i in range(NORDER):
lam += dldp[i] * dp ** i
return dy, lam
def show_beams(self, beams=['E', 'D', 'C', 'B', 'A']):
"""
Make a demo plot of the beams of a given configuration file
"""
import matplotlib.pyplot as plt
x0, x1 = 507, 507
dx = np.arange(-800, 1200)
if 'WFC3.UV' in self.conf_file:
x0, x1 = 2073, 250
dx = np.arange(-1200, 1200)
if 'G800L' in self.conf_file:
x0, x1 = 2124, 1024
dx = np.arange(-1200, 1200)
s = 200 # marker size
fig = plt.figure(figsize=[10, 3])
plt.scatter(0, 0, marker='s', s=s, color='black', edgecolor='0.8',
label='Direct')
for beam in beams:
if 'XOFF_{0}'.format(beam) not in self.conf.keys():
continue
xoff = self.field_dependent(x0, x1, self.conf['XOFF_{0}'.format(beam)])
dy, lam = self.get_beam_trace(x0, x1, dx=dx, beam=beam)
xlim = self.conf['BEAM{0}'.format(beam)]
ok = (dx >= xlim[0]) & (dx <= xlim[1])
plt.scatter(dx[ok] + xoff, dy[ok], c=lam[ok] / 1.e4, marker='s', s=s,
alpha=0.5, edgecolor='None')
plt.text(np.median(dx[ok]), np.median(dy[ok]) + 1, beam,
ha='center', va='center', fontsize=14)
print('Beam {0}, lambda=({1:.1f} - {2:.1f})'.format(beam, lam[ok].min(), lam[ok].max()))
plt.grid()
plt.xlabel(r'$\Delta x$')
plt.ylabel(r'$\Delta y$')
cb = plt.colorbar(pad=0.01, fraction=0.05)
cb.set_label(r'$\lambda\,(\mu\mathrm{m})$')
plt.title(self.conf_file)
plt.tight_layout()
plt.savefig('{0}.pdf'.format(self.conf_file))
# def load_grism_config(conf_file):
# """Load parameters from an aXe configuration file
# Parameters
# ----------
# conf_file : str
# Filename of the configuration file
# Returns
# -------
# conf : `~grizli.grismconf.aXeConf`
# Configuration file object. Runs `conf.get_beams()` to read the
# sensitivity curves.
# """
# conf = aXeConf(conf_file)
# conf.get_beams()
# return conf
from .SpecDisperser import *
from .disperse_c import disperse, interp
\ No newline at end of file
#!/usr/bin/env python
# encoding: utf-8
"""
Cython
"""
from . import disperse
from . import interp
#from .disperse import *
#from .interp import *
from __future__ import division
import numpy as np
cimport numpy as np
DTYPE = np.double
ITYPE = np.int64
ctypedef np.double_t DTYPE_t
ctypedef np.uint_t UINT_t
ctypedef np.int_t INT_t
ctypedef np.int64_t LINT_t
ctypedef np.int32_t FINT_t
ctypedef np.float32_t FTYPE_t
import cython
cdef extern from "math.h":
double sqrt(double x)
double exp(double x)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.embedsignature(True)
def disperse_grism_object(np.ndarray[FTYPE_t, ndim=2] flam,
np.ndarray[LINT_t, ndim=1] idxl,
np.ndarray[DTYPE_t, ndim=1] yfrac,
np.ndarray[DTYPE_t, ndim=1] ysens,
np.ndarray[DTYPE_t, ndim=1] full,
np.ndarray[LINT_t, ndim=1] x0,
np.ndarray[LINT_t, ndim=1] shd,
np.ndarray[LINT_t, ndim=1] shg):
"""Compute a dispersed 2D spectrum
Parameters
----------
flam : direct image matrix, 2 dim [y,x]
idxl: grating disperse light to pixel, pixel index, 1 dim, length = ysens, yfrac
yfrac:
ysense: sensitivity use pixel describe
full: output result ,1 dim, y_beam * x_beam
x0: the center of gal in image thumbnail
shd: shape of direct image
shg: shape of grating image
"""
cdef int i,j,k1,k2
cdef unsigned int nk,nl,k,shx,shy
cdef double fl_ij
nk = len(idxl)
nl = len(full)
for i in range(0-x0[1], x0[1]):
if (x0[1]+i < 0) | (x0[1]+i >= shd[1]):
continue
for j in range(0-x0[0], x0[0]):
if (x0[0]+j < 0) | (x0[0]+j >= shd[0]):
continue
fl_ij = flam[x0[0]+j, x0[1]+i] #/1.e-17
if (fl_ij == 0):
continue
for k in range(nk):
k1 = idxl[k]+j*shg[1]+i
if (k1 >= 0) & (k1 < nl):
full[k1] += ysens[k]*fl_ij*yfrac[k]
k2 = idxl[k]+(j-1)*shg[1]+i
if (k2 >= 0) & (k2 < nl):
full[k2] += ysens[k]*fl_ij*(1-yfrac[k])
return True
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.embedsignature(True)
def compute_segmentation_limits(np.ndarray[FTYPE_t, ndim=2] segm, int seg_id, np.ndarray[FTYPE_t, ndim=2] flam, np.ndarray[LINT_t, ndim=1] shd):
"""Find pixel limits of a segmentation region
Parameters
----------
segm: ndarray (np.float32)
segmentation array
seg_id: int
ID to test
flam: ndarray (float)
Flux array to compute weighted centroid within segmentation region
shd: [int, int]
Shape of segm
"""
cdef int i, j, imin, imax, jmin, jmax, area
cdef double inumer, jnumer, denom, wht_ij
area = 0
imin = shd[0]
imax = 0
jmin = shd[1]
jmax = 0
inumer = 0.
jnumer = 0.
denom = 0.
for i in range(shd[0]):
for j in range(shd[1]):
if segm[i,j] != seg_id:
continue
area += 1
wht_ij = flam[i,j]
inumer += i*wht_ij
jnumer += j*wht_ij
denom += wht_ij
if i < imin:
imin = i
if i > imax:
imax = i
if j < jmin:
jmin = j
if j > jmax:
jmax = j
### No matched pixels
if denom == 0:
denom = -99
return imin, imax, inumer/denom, jmin, jmax, jnumer/denom, area, denom
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.embedsignature(True)
def seg_flux(np.ndarray[FTYPE_t, ndim=2] flam, np.ndarray[LINT_t, ndim=1] idxl, np.ndarray[DTYPE_t, ndim=1] yfrac, np.ndarray[DTYPE_t, ndim=1] ysens, np.ndarray[DTYPE_t, ndim=1] full, np.ndarray[LINT_t, ndim=1] x0, np.ndarray[LINT_t, ndim=1] shd, np.ndarray[LINT_t, ndim=1] shg):
pass
"""
Pythonic utilities ported to C [Cython] for speedup.
"""
import numpy as np
cimport numpy as np
DTYPE = np.double
ctypedef np.double_t DTYPE_t
ctypedef np.int_t ITYPE_t
ctypedef np.uint_t UINT_t
import cython
cdef extern from "math.h":
double fabs(double)
cdef extern from"stdio.h":
extern int printf(const char *format, ...)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
@cython.embedsignature(True)
def interp_c(np.ndarray[DTYPE_t, ndim=1] x, np.ndarray[DTYPE_t, ndim=1] xp, np.ndarray[DTYPE_t, ndim=1] fp, double extrapolate=0., short int assume_sorted=1):
"""
interp_c(x, xp, fp, extrapolate=0., assume_sorted=0)
Fast interpolation: [`xp`, `fp`] interpolated at `x`.
Extrapolated values are set to `extrapolate`.
The default `assume_sorted`=1 assumes that the `x` array is sorted and single-
valued, providing a significant gain in speed. (xp is always assumed to be sorted)
"""
cdef unsigned long i, j, N, Np
cdef DTYPE_t x1,x2,y1,y2,out
cdef DTYPE_t fout, xval, xmin
N, Np = len(x), len(xp)
cdef np.ndarray[DTYPE_t, ndim=1] f = np.zeros(N)
i=0
j=0
### Handle left extrapolation
xmin = xp[0]
if assume_sorted == 1:
while x[j] < xmin:
f[j] = extrapolate
j+=1
if j>=N:
break
while j < N:
xval = x[j]
if assume_sorted == 0:
if x[j] < xmin:
f[j] = extrapolate
j+=1
continue
else:
i=0
while (xp[i] <= xval) & (i < Np-1): i+=1;
if i == (Np-1):
if x[j] != xp[i]:
f[j] = extrapolate
else:
f[j] = fp[i]
j+=1
continue
#### x[i] is now greater than xval because the
#### expression (x[i]<xval) is false, assuming
#### that xval < max(x).
# x1 = xp[i];
# x2 = xp[i+1];
# y1 = fp[i];
# y2 = fp[i+1];
x1 = xp[i-1];
x2 = xp[i];
y1 = fp[i-1];
y2 = fp[i];
out = ((y2-y1)/(x2-x1))*(xval-x1)+y1;
f[j] = out
j+=1
return f
@cython.boundscheck(False)
def interp_conserve_c(np.ndarray[DTYPE_t, ndim=1] x, np.ndarray[DTYPE_t, ndim=1] tlam, np.ndarray[DTYPE_t, ndim=1] tf, double left=0, double right=0, double integrate=0):
"""
interp_conserve_c(x, xp, fp, left=0, right=0, integrate=0)
Interpolate `xp`,`yp` array to the output x array, conserving flux.
`xp` can be irregularly spaced.
"""
cdef np.ndarray[DTYPE_t, ndim=1] templmid
cdef np.ndarray[DTYPE_t, ndim=1] tempfmid
cdef np.ndarray[DTYPE_t, ndim=1] outy
cdef unsigned long i,k,istart,ntlam,NTEMPL
cdef DTYPE_t h, numsum
# templmid = (x[1:]+x[:-1])/2. #2.+x[:-1]
# templmid = np.append(templmid, np.array([x[0], x[-1]]))
# templmid = templmid[np.argsort(templmid)]
NTEMPL = len(x)
ntlam = len(tlam)
templmid = midpoint_c(x, NTEMPL)
#tempfmid = np.interp(templmid, tlam, tf, left=left, right=right)
tempfmid = interp_c(templmid, tlam, tf, extrapolate=0.)
outy = np.zeros(NTEMPL, dtype=DTYPE)
###### Rebin template grid to master wavelength grid, conserving template flux
i=0
k=0
while templmid[k] < tlam[0]:
outy[k] = left
k+=1
if k >NTEMPL-1:
break
if(k>0) & (templmid[k-1] < tlam[0]) & (templmid[k] > tlam[0]):
m = 1;
numsum=0.;
while (tlam[m] < templmid[k]):
h = tlam[m]-tlam[m-1];
numsum+=h*(tf[m]+tf[m-1]);
m+=1;
if m >= ntlam:
break;
#print 'test #%d, %d' %(m, ntlam)
if m == 1:
h = templmid[k]-tlam[0];
numsum+=h*(tempfmid[k]+tf[0]);
else:
##### Last point
if m < ntlam:
if (templmid[k] == tlam[m]):
h = tlam[m]-tlam[m-1];
numsum+=h*(tf[m]+tf[m-1]);
else:
m-=1;
h = templmid[k]-tlam[m];
numsum+=h*(tempfmid[k]+tf[m]);
outy[k-1] = numsum*0.5;#/(templmid[k+1]-templmid[k]);
if integrate == 0.:
outy[k-1] /= (templmid[k]-templmid[k-1]);
for k in range(k, NTEMPL):
if templmid[k] > tlam[ntlam-1]:
break
numsum=0.;
#### Go to where tlam is greater than the first midpoint
while (tlam[i] < templmid[k]) & (i < ntlam): i+=1;
istart=i;
####### First point
if tlam[i] < templmid[k+1]:
h = tlam[i]-templmid[k];
numsum+=h*(tf[i]+tempfmid[k]);
i+=1;
if i==0: i+=1;
####### Template points between master grid points
while (tlam[i] < templmid[k+1]) & (i < ntlam):
h = tlam[i]-tlam[i-1];
numsum+=h*(tf[i]+tf[i-1]);
i+=1;
#### If no template points between master grid points, then just use interpolated midpoints
if i == istart:
h = templmid[k+1]-templmid[k];
numsum=h*(tempfmid[k+1]+tempfmid[k]);
else:
##### Last point
if (templmid[k+1] == tlam[i]) & (i < ntlam):
h = tlam[i]-tlam[i-1];
numsum+=h*(tf[i]+tf[i-1]);
else:
i-=1;
h = templmid[k+1]-tlam[i];
numsum+=h*(tempfmid[k+1]+tf[i]);
outy[k] = numsum*0.5;#/(templmid[k+1]-templmid[k]);
if integrate == 0.:
outy[k] /= (templmid[k+1]-templmid[k]);
return outy
def midpoint(x):
mp = (x[1:]+x[:-1])/2.
mp = np.append(mp, np.array([x[0],x[-1]]))
mp = mp[np.argsort(mp)]
return mp
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
@cython.embedsignature(True)
def midpoint_c(np.ndarray[DTYPE_t, ndim=1] x, long N):
cdef long i
cdef DTYPE_t xi,xi1
# N = len(x)
cdef np.ndarray[DTYPE_t, ndim=1] midpoint = np.zeros(N+1, dtype=DTYPE)
midpoint[0] = x[0]
midpoint[N] = x[N-1]
xi1 = x[0]
for i in range(1, N):
xi = x[i]
midpoint[i] = 0.5*xi+0.5*xi1
xi1 = xi
midpoint[0] = 2*x[0]-midpoint[1]
midpoint[N] = 2*x[N-1]-midpoint[N-1]
return midpoint
'''
Author: zx
Date: 2021-04-08 13:49:35
LastEditTime: 2022-05-17 09:36:01
LastEditors: xin zhangxinbjfu@gmail.com
Description: In User Settings Edit
FilePath: /undefined/Users/zhangxin/Work/SlitlessSim/sls_lit_demo/simDemo.py
'''
class Config(object):
def __init__(self, dataDir = '/data/'):
self.conFiles = {'GU': dataDir + 'conf/CSST_GU2.conf', 'GV': dataDir + 'conf/CSST_GV2.conf', 'GI': dataDir + 'conf/CSST_GI2.conf'}
self.thrFisle = {'GU': dataDir + 'conf/GU.Throughput', 'GV': dataDir + 'conf/GV.Throughput', 'GI': dataDir + 'conf/GI.Throughput'}
self.senFisle = {'GU': dataDir + 'conf/CSST_GU.sensitivity', 'GV': dataDir + 'conf/CSST_GV.sensitivity', 'GI': dataDir + 'conf/CSST_GI.sensitivity'}
self.orderIDs = {'A': '1st', 'B': '0st', 'C': '2st', 'D': '-1st', 'E': '-2st'}
self.bandRanges = {'GU':[2550, 4000], 'GV': [4000,6200], 'GI': [6200, 10000]}
'''
Author: zx
Date: 2021-04-08 13:49:35
LastEditTime: 2022-05-20 08:47:49
LastEditors: xin zhangxinbjfu@gmail.com
Description: In User Settings Edit
FilePath: /undefined/Users/zhangxin/Work/SlitlessSim/sls_lit_demo/simDemo.py
'''
import galsim
import SpecDisperser
# from numpy import *
import numpy as np
from scipy import interpolate
import astropy.constants as acon
from astropy.table import Table
import math
from astropy.io import fits
import random
from astropy.table import Table
import matplotlib.pyplot as plt
import mpi4py.MPI as MPI
import os,sys
from . import Config
class SpecGenerator(object):
def __init__(self,sedFn = 'a.txt', grating = 'GI', beam = 'A', aper = 2.0, xcenter = 5000,ycenter = 5000, p_size = 0.074, psf = None, skybg = 0.3, dark = 0.02, readout = 5, t = 150, expNum = 1, config = None):
self.sedFile = sedFn
self.grating = grating
self.beam = beam
self.aper = aper
self.xcenter = xcenter
self.ycenter = ycenter
self.p_size = p_size
self.psf = psf
self.skybg = skybg
self.dark = dark
self.readout = readout
self.t = t
self.expNum = expNum
self.config = config
'''
@description:
@param {*} fn: file name, include 2 column, wavelength(A) and flux(erg/s/cm2/A)
@param {*} s: band start , unit A
@param {*} e; end, unit A
@param {*} deltL: sample interval for SED
@return {*} sed, unit photo/s/m2/A
'''
def generateSEDfromFiles(self, fn, s, e, deltL):
"""
s: lambda start, unit A
e: lambda end, unit A
return:
SEDs is array, 2-dim, (gal_num+1)*(wavelength size), last row is wavelength
"""
lamb = np.arange(s, e + deltL, deltL)
spec_orig = np.loadtxt(fn)
speci = interpolate.interp1d(spec_orig[:, 0], spec_orig[:, 1])
y = speci(lamb)
# erg/s/cm2/A --> photo/s/m2/A
flux = y * lamb / (acon.h.value * acon.c.value) * 1e-13
SED = Table(np.array([lamb, flux]).T,names=('WAVELENGTH', 'FLUX'))
return SED
def generateSpec1dforGal(self, s_n = 1.0, re = 1, pa = 90,q_ell = 0.6,limitfluxratio=0.9):
specConfile = self.config.conFiles[self.grating]
throughput_f = self.config.senFisle[self.grating] + '.' + self.config.orderIDs[self.beam] + '.fits'
sed = self.generateSEDfromFiles(self.sedFile,2000,10000,0.5)
# print(skybg)
# print(specConfile)
# print(throughput_f)
# plt.figure()
# plt.plot(sed['WAVELENGTH'], sed['FLUX'])
gal = galsim.Sersic(s_n, half_light_radius=re)
gal_pa = pa * galsim.degrees
gal_ell = gal.shear(q=q_ell, beta=gal_pa)
conv_gal = galsim.Convolve([gal_ell,self.psf])
stamp = conv_gal.drawImage(wcs=galsim.PixelScale(self.p_size))*self.t*self.expNum*math.pi*(self.aper/2)*(self.aper/2)
origin_star = [self.ycenter - (stamp.center.y - stamp.ymin),
self.xcenter - (stamp.center.x - stamp.xmin)]
sdp = SpecDisperser.SpecDisperser(orig_img=stamp, xcenter=self.xcenter,
ycenter=self.ycenter, origin=origin_star,
tar_spec=sed,
conf=specConfile,
isAlongY=0)
spec_orders = sdp.compute_spec_orders()
thp = Table.read(throughput_f)
thp_i = interpolate.interp1d(thp['WAVELENGTH'], thp['SENSITIVITY'])
Aimg_orig = spec_orders[self.beam][0]
Aimg = Aimg_orig
Aimg = Aimg + (self.skybg + self.dark)*self.t*self.expNum
Aimg = np.random.poisson(Aimg)
for i in np.arange(self.expNum):
Aimg = self.addReadoutNois(img = Aimg, readout = self.readout)
Aimg = Aimg - (self.skybg + self.dark)*self.t*self.expNum
wave_pix = spec_orders[self.beam][5]
wave_pos = spec_orders[self.beam][3]
wave_pos_y=spec_orders[self.beam][4]
sh = Aimg.shape
spec_pix = np.zeros(sh[1])
err2_pix = np.zeros(sh[1])
# print(spec_orders[beamOrder][4])
# print(sh)
# plt.figure()
# plt.imshow(Aimg)
y_cent_pos = int(np.round(np.mean(wave_pos_y)))
tFlux = np.sum(spec_orders[self.beam][0])
# print(tFlux)
fluxRatio = 0
for i in range(int(sh[0]/2)):
pFlux = np.sum(spec_orders[self.beam][0][y_cent_pos-i:y_cent_pos+i+1])
fluxRatio = pFlux/tFlux
if fluxRatio>limitfluxratio:
break
y_range = i
# print(y_range, fluxRatio)
y_len_pix = 2 * y_range + 1
for i in range(sh[1]):
spec_pix[i] = sum(Aimg[y_cent_pos-y_range:y_cent_pos+y_range+1, i])
err2_pix[i] = sum(Aimg_orig[y_cent_pos-y_range:y_cent_pos+y_range+1, i]) + (self.skybg + self.dark)*self.t * y_len_pix * self.expNum + self.readout*self.readout * y_len_pix * self.expNum
bRange = self.config.bandRanges[self.grating]
wave_flux = np.zeros(wave_pix.shape[0])
err_flux = np.zeros(wave_pix.shape[0])
for i in np.arange(1, wave_pix.shape[0] - 1):
w = wave_pix[i]
if (bRange[0] <= w <= bRange[1]):
thp_w = thp_i(w)
deltW = (w - wave_pix[i - 1]) / 2 + (wave_pix[i + 1] - w) / 2
f = spec_pix[wave_pos[0] - 1 + i]
f = f / t / thp_w / deltW /self.expNum
err = err2_pix[wave_pos[0] - 1 + i]
# err = err/ t / deltW
err = np.sqrt(err)/ self.t / deltW/ thp_w /self.expNum
# err = err / thp_w
else:
f = 0
err = 0
wave_flux[i] = f
err_flux[i] = err
idx = (wave_pix >= bRange[0]-100)
idx1 = (wave_pix[idx] <= bRange[1]+100)
specTab = Table(np.array([wave_pix[idx][idx1], wave_flux[idx][idx1], err_flux[idx][idx1]]).T,names=('WAVELENGTH', 'FLUX','ERR'))
# spec_orig = np.loadtxt(sedFile)
# plt.figure()
# plt.plot(spec_orig[:,0], spec_orig[:,1])
plt.figure()
plt.errorbar(wave_pix[idx][idx1], wave_flux[idx][idx1],err_flux[idx][idx1])
plt.legend([self.sedFile])
# plt.plot(wave_pix[idx][idx1], wave_flux[idx][idx1])
plt.show()
return specTab, Aimg, stamp.array
def generateSpec1dforStar(self,limitfluxratio = 0.8):
specConfile = self.config.conFiles[self.grating]
throughput_f = self.config.senFisle[self.grating] + '.' + self.config.orderIDs[self.beam] + '.fits'
sed = self.generateSEDfromFiles(self.sedFile,2000,10000,0.5)
stamp = self.psf.drawImage(wcs=galsim.PixelScale(self.p_size))*self.t*self.expNum*math.pi*(self.aper/2)*(self.aper/2)
origin_star = [self.ycenter - (stamp.center.y - stamp.ymin),
self.xcenter - (stamp.center.x - stamp.xmin)]
sdp = SpecDisperser.SpecDisperser(orig_img=stamp, xcenter=self.xcenter,
ycenter=self.ycenter, origin=origin_star,
tar_spec=sed,
conf=specConfile,
isAlongY=0)
spec_orders = sdp.compute_spec_orders()
thp = Table.read(throughput_f)
thp_i = interpolate.interp1d(thp['WAVELENGTH'], thp['SENSITIVITY'])
Aimg_orig = spec_orders[self.beam][0]
Aimg = Aimg_orig
Aimg = Aimg + (self.skybg + self.dark)*self.t*self.expNum
Aimg = np.random.poisson(Aimg)
for i in np.arange(self.expNum):
Aimg = self.addReadoutNois(img = Aimg, readout = self.readout)
Aimg = Aimg - (self.skybg + self.dark)*self.t*self.expNum
wave_pix = spec_orders[self.beam][5]
wave_pos = spec_orders[self.beam][3]
wave_pos_y=spec_orders[self.beam][4]
sh = Aimg.shape
spec_pix = np.zeros(sh[1])
err2_pix = np.zeros(sh[1])
# print(spec_orders[beamOrder][4])
# print(sh)
# plt.figure()
# plt.imshow(Aimg)
y_cent_pos = int(np.round(np.mean(wave_pos_y)))
tFlux = np.sum(spec_orders[self.beam][0])
# print(tFlux)
fluxRatio = 0
for i in range(int(sh[0]/2)):
pFlux = np.sum(spec_orders[self.beam][0][y_cent_pos-i:y_cent_pos+i+1])
fluxRatio = pFlux/tFlux
if fluxRatio>limitfluxratio:
break
y_range = i
# print(y_range, fluxRatio)
y_len_pix = 2 * y_range + 1
for i in range(sh[1]):
spec_pix[i] = sum(Aimg[y_cent_pos-y_range:y_cent_pos+y_range+1, i])
err2_pix[i] = sum(Aimg_orig[y_cent_pos-y_range:y_cent_pos+y_range+1, i]) + (self.skybg + self.dark)*self.t * y_len_pix * self.expNum + self.readout*self.readout * y_len_pix * self.expNum
bRange = self.config.bandRanges[self.grating]
wave_flux = np.zeros(wave_pix.shape[0])
err_flux = np.zeros(wave_pix.shape[0])
for i in np.arange(1, wave_pix.shape[0] - 1):
w = wave_pix[i]
if (bRange[0] <= w <= bRange[1]):
thp_w = thp_i(w)
deltW = (w - wave_pix[i - 1]) / 2 + (wave_pix[i + 1] - w) / 2
f = spec_pix[wave_pos[0] - 1 + i]
f = f / self.t / thp_w / deltW /self.expNum
err = err2_pix[wave_pos[0] - 1 + i]
# err = err/ t / deltW
err = np.sqrt(err)/ self.t / deltW/ thp_w /self.expNum
# err = err / thp_w
else:
f = 0
err = 0
wave_flux[i] = f
err_flux[i] = err
idx = (wave_pix >= bRange[0]-100)
idx1 = (wave_pix[idx] <= bRange[1]+100)
specTab = Table(np.array([wave_pix[idx][idx1], wave_flux[idx][idx1], err_flux[idx][idx1]]).T,names=('WAVELENGTH', 'FLUX','ERR'))
# spec_orig = np.loadtxt(sedFile)
# plt.figure()
# plt.plot(spec_orig[:,0], spec_orig[:,1])
# plt.figure()
# plt.errorbar(wave_pix[idx][idx1], wave_flux[idx][idx1],err_flux[idx][idx1])
# plt.legend([self.sedFile])
# # plt.plot(wave_pix[idx][idx1], wave_flux[idx][idx1])
# plt.show()
return specTab, Aimg, stamp.array, fluxRatio
def addReadoutNois(self, img = None, readout = 5):
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img[i,j] += round(random.gauss(mu = 0, sigma = readout))
return img
'''
Author: xin zhangxinbjfu@gmail.com
Date: 2021-04-08 13:49:35
LastEditors: xin zhangxinbjfu@gmail.com
LastEditTime: 2022-05-18 08:31:10
FilePath: /undefined/Users/zhangxin/Work/SlitlessSim/sls_lit_demo/SpecGen/__init__.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''
File added
INSTRUMETN CSSTSLS
GRATING GI
WAVELENGTH 6200 10000
# First order (BEAM A) *******************
BEAMA -1124 -577
MMAG_EXTRACT_A 30
MMAG_MARK_A 30
#
# Trace description
#
DYDX_ORDER_A 1
DYDX_A_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_A_1 -0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_A 0.0
YOFF_A 0.0
#
# Dispersion solution
#
DISP_ORDER_A 1
DLDP_A_0 -33.01210344165788 0.007569610429352271 -0.0022577397703360323 -8.214442647976815e-07 -4.592086832501138e-09 2.5239465714847694e-07
DLDP_A_1 -9.200968629784002 -0.0002566886334429964 9.500220330081724e-05 2.7855490962881916e-08 2.858304867205082e-11 -1.0450952273741693e-08
#
SENSITIVITY_A GI.Throughput.1st.fits
#
#zero order (BEAM B) *******************
BEAMB -10 10
MMAG_EXTRACT_B 30.
MMAG_MARK_B 30.
#
# Trace description
#
DYDX_ORDER_B 0
DYDX_B_00.0 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_B 0.0
YOFF_B 0.0
#
# Dispersion solution
#
DISP_ORDER_B 1
DLDP_B_0 8100.0 0.0 0.0 0.0 0.0 0.0
DLDP_B_1 -3800.0 0.0 0.0 0.0 0.0 0.0
#
#
SENSITIVITY_B GI.Throughput.0st.fits
# Sencond order (BEAM C) *******************
BEAMC -2148 -1254
MMAG_EXTRACT_C 30
MMAG_MARK_C 30
#
# Trace description
#
DYDX_ORDER_C 1
DYDX_C_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_C_1 -0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_C 0.0
YOFF_C 0.0
#
# Dispersion solution
#
DISP_ORDER_C 1
DLDP_C_0 -33.01210344165788 0.007569610429352271 -0.0022577397703360323 -8.214442647976815e-07 -4.592086832501138e-09 2.5239465714847694e-07
DLDP_C_1 -4.600484314892002 -0.00012834431672149928 4.750110165041072e-05 1.3927745481441094e-08 1.4291524335939302e-11 -5.225476136871006e-09
#
SENSITIVITY_C GI.Throughput.2st.fits
#
# -1st order (BEAM D) *******************
BEAMD 535 1191
MMAG_EXTRACT_D 30
MMAG_MARK_D 30
#
# Trace description
#
DYDX_ORDER_D 1
DYDX_D_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_D_1 0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_D 0.0
YOFF_D 0.0
#
# Dispersion solution
#
DISP_ORDER_D 1
DLDP_D_0 -33.01210344165788 0.007569610429352271 -0.0022577397703360323 -8.214442647976815e-07 -4.592086832501138e-09 2.5239465714847694e-07
DLDP_D_1 9.200968629784002 0.0002566886334429964 -9.500220330081724e-05 -2.7855490962881916e-08 -2.858304867205082e-11 1.0450952273741693e-08
#
SENSITIVITY_D GI.Throughput.-1st.fits
#
# -2st order (BEAM E) *******************
BEAME 1170 2281
MMAG_EXTRACT_E 30
MMAG_MARK_E 30
#
# Trace description
#
DYDX_ORDER_E 1
DYDX_E_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_E_1 0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_E 0.0
YOFF_E 0.0
#
# Dispersion solution
#
DISP_ORDER_E 1
DLDP_E_0 -33.01210344165788 0.007569610429352271 -0.0022577397703360323 -8.214442647976815e-07 -4.592086832501138e-09 2.5239465714847694e-07
DLDP_E_1 4.600484314892002 0.00012834431672149928 -4.750110165041072e-05 -1.3927745481441094e-08 -1.4291524335939302e-11 5.225476136871006e-09
#
SENSITIVITY_E GI.Throughput.-2st.fits
#
INSTRUMETN CSSTSLS
GRATING GI
WAVELENGTH 6200 10000
# First order (BEAM A) *******************
BEAMA 516 1230
MMAG_EXTRACT_A 30
MMAG_MARK_A 30
#
# Trace description
#
DYDX_ORDER_A 1
DYDX_A_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_A_1 0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_A 0.0
YOFF_A 0.0
#
# Dispersion solution
#
DISP_ORDER_A 1
DLDP_A_0 175.81371583954845 0.00046898716015618923 0.0011751407556484514 6.967374268344785e-07 -1.0886921620684591e-08 -1.1934641681891917e-07
DLDP_A_1 9.7236437973885 -4.0899320307831585e-05 -0.00010248139112795352 -6.50820335441285e-08 -2.968125617588231e-10 1.16888694637088e-08
#
SENSITIVITY_A GI.Throughput.1st.fits
#
#zero order (BEAM B) *******************
BEAMB -10 10
MMAG_EXTRACT_B 30.
MMAG_MARK_B 30.
#
# Trace description
#
DYDX_ORDER_B 0
DYDX_B_00.0 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_B 0.0
YOFF_B 0.0
#
# Dispersion solution
#
DISP_ORDER_B 1
DLDP_B_0 8100.0 0.0 0.0 0.0 0.0 0.0
DLDP_B_1 3800.0 0.0 0.0 0.0 0.0 0.0
#
#
SENSITIVITY_B GI.Throughput.0st.fits
# Sencond order (BEAM C) *******************
BEAMC 1132 2359
MMAG_EXTRACT_C 30
MMAG_MARK_C 30
#
# Trace description
#
DYDX_ORDER_C 1
DYDX_C_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_C_1 0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_C 0.0
YOFF_C 0.0
#
# Dispersion solution
#
DISP_ORDER_C 1
DLDP_C_0 175.81371583954845 0.00046898716015618923 0.0011751407556484514 6.967374268344785e-07 -1.0886921620684591e-08 -1.1934641681891917e-07
DLDP_C_1 4.86182189869425 -2.0449659998483498e-05 -5.1240695626007864e-05 -3.2541016814255404e-08 -1.4840628087939621e-10 5.8444347385742755e-09
#
SENSITIVITY_C GI.Throughput.2st.fits
#
# -1st order (BEAM D) *******************
BEAMD -1106 -591
MMAG_EXTRACT_D 30
MMAG_MARK_D 30
#
# Trace description
#
DYDX_ORDER_D 1
DYDX_D_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_D_1 -0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_D 0.0
YOFF_D 0.0
#
# Dispersion solution
#
DISP_ORDER_D 1
DLDP_D_0 175.81371583954845 0.00046898716015618923 0.0011751407556484514 6.967374268344785e-07 -1.0886921620684591e-08 -1.1934641681891917e-07
DLDP_D_1 -9.7236437973885 4.0899320307831585e-05 0.00010248139112795352 6.50820335441285e-08 2.968125617588231e-10 -1.16888694637088e-08
#
SENSITIVITY_D GI.Throughput.-1st.fits
#
# -2st order (BEAM E) *******************
BEAME -2111 -1283
MMAG_EXTRACT_E 30
MMAG_MARK_E 30
#
# Trace description
#
DYDX_ORDER_E 1
DYDX_E_0 0.0 0.0 0.0 0.0 0.0 0.0
DYDX_E_1 -0.0008726648475212713 0.0 0.0 0.0 0.0 0.0
#
# X and Y Offsets
#
XOFF_E 0.0
YOFF_E 0.0
#
# Dispersion solution
#
DISP_ORDER_E 1
DLDP_E_0 175.81371583954845 0.00046898716015618923 0.0011751407556484514 6.967374268344785e-07 -1.0886921620684591e-08 -1.1934641681891917e-07
DLDP_E_1 -4.86182189869425 2.0449659998483498e-05 5.1240695626007864e-05 3.2541016814255404e-08 1.4840628087939621e-10 -5.8444347385742755e-09
#
SENSITIVITY_E GI.Throughput.-2st.fits
#
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment