ESBO-ETC/esbo_etc/classes/psf/IPSF.py

87 lines
2.8 KiB
Python

from abc import ABC, abstractmethod
import astropy.units as u
from ..sensor.PixelMask import PixelMask
from typing import Union
import numpy as np
class IPSF(ABC):
"""
Interface for modelling a PSF
"""
@abstractmethod
def calcReducedObservationAngle(self, contained_energy: Union[str, int, float, u.Quantity],
jitter_sigma: u.Quantity = None, obstruction: float = 0.0) -> u.Quantity:
"""
Calculate the reduced observation angle in lambda / d_ap for the given contained energy.
Parameters
----------
contained_energy : Union[str, int, float, u.Quantity]
The percentage of energy to be contained within a circle with the diameter reduced observation angle.
jitter_sigma : Quantity
Sigma of the telescope's jitter in arcsec
obstruction : float
The central obstruction as ratio A_ob / A_ap
Returns
-------
reduced_observation_angle: Quantity
The reduced observation angle in lambda / d_ap
"""
pass
@abstractmethod
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
@staticmethod
def _rebin(arr: np.ndarray, factor: float):
"""
Rebin a 2D-array by summing or repeating the elements.
Parameters
----------
arr : ndarray
Input array.
factor : float
Rebinning factor
Returns
-------
rebinned_array : ndarray
If the factor is smaller than 1, the data is summed,
if the factor is bigger than 1, array elements are repeated
See Also
--------
resize : Return a new array with the specified factor.
"""
m, n = arr.shape
m_new, n_new = int(m * factor), int(n * factor)
if factor < 1:
res = arr.reshape((m_new, int(1 / factor), n_new, int(1 / factor))).sum(3).sum(1)
elif factor > 1:
res = np.repeat(np.repeat(arr, int(factor), axis=0), int(factor), axis=1)
else:
res = arr
if isinstance(arr, PixelMask):
res.pixel_size = res.pixel_size / factor
return res