Newer
Older
def __init__(self, chip, fdModel=None, fdModel_path=None, img_rot=0.):
if hasattr(chip, 'fdModel'):
self.fdModel = chip.fdModel
elif fdModel_path is not None:
import pickle
with open(fdModel_path, "rb") as f:
self.fdModel = pickle.load(f)
else:
raise ValueError("Error: no field distortion model has been specified!")
self.img_rot = img_rot
self.ifdModel = self.fdModel["wave1"]
self.ixfdModel = self.ifdModel["xImagePos"]
self.iyfdModel = self.ifdModel["yImagePos"]
# first-order derivatives of the global field distortion model
self.ifx_dx = self.ixfdModel.partial_derivative(1,0)
self.ifx_dy = self.ixfdModel.partial_derivative(0,1)
self.ify_dx = self.iyfdModel.partial_derivative(1,0)
self.ify_dy = self.iyfdModel.partial_derivative(0,1)
if "residual" in self.fdModel["wave1"]:
self.irsModel = self.fdModel["wave1"]["residual"]["ccd" + chip.getChipLabel(chipID=chip.chipID)]
self.ixrsModel = self.irsModel["xResidual"]
self.iyrsModel = self.irsModel["yResidual"]
# first-order derivatives of the residual field distortion model
self.irx_dx = self.ixrsModel.partial_derivative(1,0)
self.irx_dy = self.ixrsModel.partial_derivative(0,1)
self.iry_dx = self.iyrsModel.partial_derivative(1,0)
self.iry_dy = self.iyrsModel.partial_derivative(0,1)
else:
self.irsModel = None
if (xLowI - x) * (xUpI - x) > 0 or (yLowI - y) * (yUpI - y) > 0:
def get_distorted(self, chip, pos_img, bandpass=None, img_rot=None):
""" Get the distored position for an undistorted image position
Parameters:
chip: A 'Chip' object representing the
chip we want to extract PSF from.
pos_img: A 'galsim.Position' object representing
the image position.
bandpass: A 'galsim.Bandpass' object representing
the wavelength range.
Returns:
pos_distorted: A 'galsim.Position' object representing
the distored position.
"""
if not self.isContainObj_FD(chip=chip, pos_img=pos_img):
if not img_rot:
img_rot = np.radians(self.img_rot)
else:
img_rot = np.radians(img_rot)
x = self.ixfdModel(x, y)[0][0]
y = self.iyfdModel(x, y)[0][0]
# x1LowI, x1UpI, y1LowI, y1UpI = self.irsModel["interpLimit"]
# if (x1LowI-x)*(x1UpI-x) <=0 and (y1LowI-y)*(y1UpI-y)<=0:
# dx = self.ixrsModel(x, y)[0][0]
# dy = self.iyrsModel(x, y)[0][0]
# x += dx
# y += dy
# # field distortion induced ellipticity
# ix_dx = self.ifx_dx(x, y) + self.irx_dx(x, y)
# ix_dy = self.ifx_dy(x, y) + self.irx_dy(x, y)
# iy_dx = self.ify_dx(x, y) + self.iry_dx(x, y)
# iy_dy = self.ify_dy(x, y) + self.iry_dy(x, y)
# else:
# return galsim.PositionD(-1, -1), None
dx = self.ixrsModel(x, y)[0][0]
dy = self.iyrsModel(x, y)[0][0]
x += dx
y += dy
# field distortion induced ellipticity
ix_dx = self.ifx_dx(x, y) + self.irx_dx(x, y)
ix_dy = self.ifx_dy(x, y) + self.irx_dy(x, y)
iy_dx = self.ify_dx(x, y) + self.iry_dx(x, y)
iy_dy = self.ify_dy(x, y) + self.iry_dy(x, y)
else:
ix_dx = self.ifx_dx(x, y)
ix_dy = self.ifx_dy(x, y)
iy_dx = self.ify_dx(x, y)
iy_dy = self.ify_dy(x, y)
g1k_fd = 0.0 + (iy_dy - ix_dx) / (iy_dy + ix_dx)
g2k_fd = 0.0 - (iy_dx + ix_dy) / (iy_dy + ix_dx)
# [TODO] [TESTING] Rotate the shear:
g_abs = np.sqrt(g1k_fd**2 + g2k_fd**2)
phi = cmath.phase(complex(g1k_fd, g2k_fd))
# g_abs = 0.7
g1k_fd = g_abs * np.cos(phi + 2*img_rot)
g2k_fd = g_abs * np.sin(phi + 2*img_rot)
fd_shear = galsim.Shear(g1=g1k_fd, g2=g2k_fd)
return galsim.PositionD(x, y), fd_shear