ESBO-ETC/esbo_etc/classes/optical_component/AOpticalComponent.py

145 lines
5.6 KiB
Python
Raw Normal View History

2020-04-16 09:35:24 +02:00
from ..IRadiant import IRadiant
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-16 09:35:24 +02:00
class AOpticalComponent(IRadiant):
"""
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,
obstructor_temp: u.Quantity = 0 * u.K, obstructor_emissivity: float = 1):
"""
Initialize a new optical component
Parameters
----------
2020-04-16 09:35:24 +02:00
parent : IRadiant
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]
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.
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-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
def calcSignal(self) -> Tuple[SpectralQty, float]:
"""
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.
"""
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))
return signal, obstruction
def calcBackground(self) -> SpectralQty:
"""
Calculate the spectral radiance of the background
Returns
-------
background : SpectralQty
The spectral radiance of the background
"""
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
background = parent * (1. - self.__obstruction) + obstructor * self.__obstruction
2020-04-09 17:51:55 +02:00
else:
background = parent * (1. - self.__obstruction)
background = background + self._ownNoise()
2020-10-01 16:42:35 +02:00
logger.debug(os.linesep + str(background))
return background
2020-04-14 19:56:10 +02:00
2020-04-16 13:04:21 +02:00
def _propagate(self, rad: SpectralQty) -> SpectralQty:
"""
Propagate incoming radiation through the optical component
Parameters
----------
2020-04-16 13:04:21 +02:00
rad : SpectralQty
The incoming radiation
Returns
-------
2020-04-16 13:04:21 +02:00
rad : SpectralQty
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-16 13:04:21 +02:00
def _ownNoise(self) -> Union[SpectralQty, Callable[[u.Quantity], u.Quantity], int, float]:
"""
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]
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