2020-04-16 09:35:24 +02:00
|
|
|
from ..IRadiant import IRadiant
|
2020-04-08 18:21:14 +02:00
|
|
|
from ..SpectralQty import SpectralQty
|
2020-05-29 09:36:02 +02:00
|
|
|
from ...lib.logger import logger
|
2020-04-16 09:35:24 +02:00
|
|
|
from abc import abstractmethod
|
2020-04-09 17:51:55 +02:00
|
|
|
import astropy.units as u
|
|
|
|
from astropy.modeling.models import BlackBody
|
2020-04-28 17:21:26 +02:00
|
|
|
from typing import Union, Callable, Tuple
|
2020-05-08 15:06:13 +02:00
|
|
|
from ..Entry import Entry
|
2020-10-01 16:42:35 +02:00
|
|
|
import os
|
2020-04-08 18:21:14 +02:00
|
|
|
|
|
|
|
|
2020-04-16 09:35:24 +02:00
|
|
|
class AOpticalComponent(IRadiant):
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
|
|
|
Abstract super class for an optical component
|
|
|
|
"""
|
|
|
|
|
|
|
|
@abstractmethod
|
2020-04-09 17:51:55 +02:00
|
|
|
@u.quantity_input(obstructor_temp=[u.K, u.Celsius])
|
2020-04-16 09:35:24 +02:00
|
|
|
def __init__(self, parent: IRadiant, transreflectivity: Union[SpectralQty, int, float, u.Quantity] = None,
|
2020-06-18 09:03:10 +02:00
|
|
|
noise: Union[SpectralQty, int, float, u.Quantity, Callable] = None, obstruction: float = 0,
|
2020-04-14 19:57:33 +02:00
|
|
|
obstructor_temp: u.Quantity = 0 * u.K, obstructor_emissivity: float = 1):
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
|
|
|
Initialize a new optical component
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
2020-04-16 09:35:24 +02:00
|
|
|
parent : IRadiant
|
2020-04-08 18:21:14 +02:00
|
|
|
The parent element of the optical component from which the electromagnetic radiation is received
|
2020-06-18 09:03:10 +02:00
|
|
|
transreflectivity : Union[SpectralQty, int, float, u.Quantity]
|
2020-04-08 18:21:14 +02:00
|
|
|
The spectral transmission / reflectivity coefficient of the component. This coefficient is multiplied with
|
|
|
|
the incoming radiation from the parent element in order to propagate the incoming radiation through the
|
|
|
|
optical component.
|
2020-06-18 09:03:10 +02:00
|
|
|
noise : Union[SpectralQty, int, float, u.Quantity, Callable]
|
2020-04-14 13:12:40 +02:00
|
|
|
The noise created by the optical component as spectral radiance. This noise will be added to the propagated
|
|
|
|
incoming noise in order to calculate the overall noise.
|
2020-04-08 18:21:14 +02:00
|
|
|
obstruction : float
|
|
|
|
The additional obstruction factor of the optical component. 0 means the component is not obstructed, 1
|
|
|
|
denotes a completely obstructed component with therefore no incoming flux. It is important to note, that
|
|
|
|
the obstruction factor reflects the obstruction of the optical component additionally to the obstruction
|
|
|
|
factors of the prior elements in the beam.
|
2020-04-09 17:51:55 +02:00
|
|
|
obstructor_temp : Quantity in Kelvin / Celsius
|
|
|
|
Temperature of the obstructing component.
|
|
|
|
obstructor_emissivity : float
|
|
|
|
Emissivity of the obstructing component.
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
2020-04-16 13:04:21 +02:00
|
|
|
self.__parent = parent
|
2020-06-18 09:03:10 +02:00
|
|
|
if transreflectivity is not None:
|
2020-04-16 13:04:21 +02:00
|
|
|
self.__transreflectivity = transreflectivity
|
2020-06-08 11:34:49 +02:00
|
|
|
if noise is not None:
|
2020-04-16 13:04:21 +02:00
|
|
|
self.__noise = noise
|
|
|
|
self.__obstruction = obstruction
|
|
|
|
self.__obstructor_temp = obstructor_temp
|
|
|
|
self.__obstructor_emissivity = obstructor_emissivity
|
2020-04-08 18:21:14 +02:00
|
|
|
|
2020-06-26 19:15:43 +02:00
|
|
|
def calcSignal(self) -> Tuple[SpectralQty, float]:
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
|
|
|
Calculate the spectral flux density of the target's signal
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
signal : SpectralQty
|
|
|
|
The spectral flux density of the target's signal
|
2020-05-08 17:21:33 +02:00
|
|
|
obstruction : float
|
2020-05-15 14:34:16 +02:00
|
|
|
The obstruction factor as A_ob / A_ap.
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
2020-06-26 19:15:43 +02:00
|
|
|
signal, obstruction = self.__parent.calcSignal()
|
2020-05-29 09:36:02 +02:00
|
|
|
logger.info("Calculating signal for class '" + self.__class__.__name__ + "'.")
|
2020-04-24 11:05:01 +02:00
|
|
|
signal = self._propagate(signal) * (1 - self.__obstruction)
|
2020-05-08 17:21:33 +02:00
|
|
|
obstruction = obstruction + self.__obstruction
|
2020-10-01 16:42:35 +02:00
|
|
|
logger.debug(os.linesep + str(signal))
|
2020-06-26 19:15:43 +02:00
|
|
|
return signal, obstruction
|
2020-04-08 18:21:14 +02:00
|
|
|
|
2020-04-24 17:10:08 +02:00
|
|
|
def calcBackground(self) -> SpectralQty:
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
2020-04-24 17:10:08 +02:00
|
|
|
Calculate the spectral radiance of the background
|
2020-04-08 18:21:14 +02:00
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
2020-04-24 17:10:08 +02:00
|
|
|
background : SpectralQty
|
|
|
|
The spectral radiance of the background
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
2020-04-24 17:10:08 +02:00
|
|
|
parent = self.__parent.calcBackground()
|
2020-05-29 09:36:02 +02:00
|
|
|
logger.info("Calculating background for class '" + self.__class__.__name__ + "'.")
|
2020-04-24 11:05:01 +02:00
|
|
|
parent = self._propagate(parent)
|
2020-04-16 13:04:21 +02:00
|
|
|
if self.__obstructor_temp > 0 * u.K:
|
|
|
|
bb = BlackBody(temperature=self.__obstructor_temp, scale=1. * u.W / (u.m ** 2 * u.nm * u.sr))
|
|
|
|
obstructor = bb(parent.wl) * self.__obstructor_emissivity
|
2020-04-24 17:10:08 +02:00
|
|
|
background = parent * (1. - self.__obstruction) + obstructor * self.__obstruction
|
2020-04-09 17:51:55 +02:00
|
|
|
else:
|
2020-04-24 17:10:08 +02:00
|
|
|
background = parent * (1. - self.__obstruction)
|
|
|
|
background = background + self._ownNoise()
|
2020-10-01 16:42:35 +02:00
|
|
|
logger.debug(os.linesep + str(background))
|
2020-04-24 17:10:08 +02:00
|
|
|
return background
|
2020-04-14 19:56:10 +02:00
|
|
|
|
2020-04-16 13:04:21 +02:00
|
|
|
def _propagate(self, rad: SpectralQty) -> SpectralQty:
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
|
|
|
Propagate incoming radiation through the optical component
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
2020-04-16 13:04:21 +02:00
|
|
|
rad : SpectralQty
|
2020-04-08 18:21:14 +02:00
|
|
|
The incoming radiation
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
2020-04-16 13:04:21 +02:00
|
|
|
rad : SpectralQty
|
2020-04-08 18:21:14 +02:00
|
|
|
Manipulated incoming radiation
|
|
|
|
"""
|
2020-04-16 13:04:21 +02:00
|
|
|
try:
|
|
|
|
return rad * self.__transreflectivity
|
|
|
|
except AttributeError:
|
2020-05-29 09:36:02 +02:00
|
|
|
logger.error("Transreflectivity not given. Method propagate() needs to be implemented.")
|
2020-04-08 18:21:14 +02:00
|
|
|
|
2020-04-16 13:04:21 +02:00
|
|
|
def _ownNoise(self) -> Union[SpectralQty, Callable[[u.Quantity], u.Quantity], int, float]:
|
2020-04-08 18:21:14 +02:00
|
|
|
"""
|
|
|
|
Calculate the noise created by the optical component
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
2020-04-16 13:04:21 +02:00
|
|
|
noise : Union[SpectralQty, Callable[[u.Quantity], u.Quantity], int, float]
|
2020-04-08 18:21:14 +02:00
|
|
|
The noise created by the optical component
|
|
|
|
"""
|
2020-04-16 13:04:21 +02:00
|
|
|
try:
|
|
|
|
return self.__noise
|
|
|
|
except AttributeError:
|
2020-05-29 09:36:02 +02:00
|
|
|
logger.error("noise not given. Method ownNoise() needs to be implemented.")
|
2020-05-08 15:06:13 +02:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@abstractmethod
|
|
|
|
def check_config(conf: Entry) -> Union[None, str]:
|
|
|
|
"""
|
|
|
|
Check the configuration for this class
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
conf : Entry
|
|
|
|
The configuration entry to be checked.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
mes : Union[None, str]
|
|
|
|
The error message of the check. This will be None if the check was successful.
|
|
|
|
"""
|
|
|
|
pass
|