mapToPixelMask implemented
This commit is contained in:
parent
10038014f8
commit
b322740fb7
@ -7,6 +7,7 @@ from scipy.optimize import newton, fmin, bisect
|
||||
from scipy.special import j0, j1
|
||||
from scipy.signal import fftconvolve
|
||||
from scipy.integrate import quad
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
|
||||
class Airy(IPSF):
|
||||
@ -207,20 +208,59 @@ class Airy(IPSF):
|
||||
# See also https://en.wikipedia.org/wiki/Airy_disk#Mathematical_formulation
|
||||
return 1 - j0(x) ** 2 - j1(x) ** 2
|
||||
|
||||
def mapToPixelMask(self, mask: PixelMask, jitter_sigma: u.Quantity = None) -> PixelMask:
|
||||
def mapToPixelMask(self, mask: PixelMask, jitter_sigma: u.Quantity = None, obstruction: float = 0.0) -> PixelMask:
|
||||
"""
|
||||
Map the integrated PSF values to a sensor grid.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obstruction
|
||||
mask : PixelMask
|
||||
The pixel mask to map the values to. The values will only be mapped onto entries with the value 1.
|
||||
jitter_sigma : Quantity
|
||||
Sigma of the telescope's jitter in arcsec
|
||||
obstruction : float
|
||||
The central obstruction as ratio A_ob / A_ap
|
||||
|
||||
Returns
|
||||
-------
|
||||
mask : PixelMask
|
||||
The pixel mask with the integrated PSF values mapped onto each pixel.
|
||||
"""
|
||||
pass
|
||||
# Calculate the indices of all non-zero elements of the mask
|
||||
y_ind, x_ind = np.nonzero(mask)
|
||||
# Extract a rectangle containing all non-zero values of the mask
|
||||
mask_red = mask[y_ind.min():(y_ind.max() + 1), x_ind.min():(x_ind.max() + 1)]
|
||||
# Calculate the new PSF-center indices of the reduced mask
|
||||
psf_center_ind = [mask.psf_center_ind[0] - y_ind.min(), mask.psf_center_ind[1] - x_ind.min()]
|
||||
# Oversample the reduced mask
|
||||
mask_red_os = self.rebin(mask_red, self.__osf).view(PixelMask)
|
||||
# Calculate the new PSF-center indices of the reduced mask
|
||||
psf_center_ind = [x * self.__osf for x in psf_center_ind]
|
||||
|
||||
reduced_observation_angle_pixel = (mask.pixel_size / (
|
||||
self.__f_number * self.__d_aperture) * self.__d_aperture / self.__wl).decompose()
|
||||
x_mesh, y_mesh = np.meshgrid(
|
||||
(np.arange(mask_red_os.shape[1]) - psf_center_ind[
|
||||
1]) * reduced_observation_angle_pixel.value / self.__osf,
|
||||
(np.arange(mask_red_os.shape[0]) - psf_center_ind[
|
||||
0]) * reduced_observation_angle_pixel.value / self.__osf)
|
||||
dist = np.sqrt(x_mesh ** 2 + y_mesh ** 2)
|
||||
if jitter_sigma is None:
|
||||
res = self.airy(dist * np.pi, np.sqrt(obstruction))
|
||||
else:
|
||||
if self.__psf_jitter is None:
|
||||
self.calcReducedObservationAngle("fwhm", jitter_sigma, obstruction)
|
||||
psf_jitter = self.__psf_jitter
|
||||
x = np.arange(psf_jitter.shape[0]) * reduced_observation_angle_pixel.value / self.__osf
|
||||
psf_interp = interp1d(x=x, y=psf_jitter, kind='cubic', copy=False, bounds_error=False,
|
||||
fill_value="extrapolate")
|
||||
res = psf_interp(dist)
|
||||
|
||||
res = self.rebin(res, 1 / self.__osf)
|
||||
res = (mask_red * res).view(np.ndarray)
|
||||
# Integrate the reduced mask and divide by the indefinite integral to get relative intensities
|
||||
res = res * (reduced_observation_angle_pixel.value / self.__osf) ** 2 / (4 / np.pi) * (1 - obstruction) ** 2
|
||||
# reintegrate the reduced mask into the complete mask
|
||||
mask[y_ind.min():(y_ind.max() + 1), x_ind.min():(x_ind.max() + 1)] = res
|
||||
return mask
|
||||
|
Loading…
x
Reference in New Issue
Block a user