Filter added
This commit is contained in:
parent
afd3a0bf6d
commit
24de24aa6a
199
esbo_etc/classes/optical_component/Filter.py
Normal file
199
esbo_etc/classes/optical_component/Filter.py
Normal file
@ -0,0 +1,199 @@
|
||||
from .AHotOpticalComponent import AHotOpticalComponent
|
||||
from ..SpectralQty import SpectralQty
|
||||
from ..ITransmissive import ITransmissive
|
||||
from ...lib.helpers import error
|
||||
from astropy import units as u
|
||||
from typing import Union, Callable
|
||||
|
||||
|
||||
class Filter(AHotOpticalComponent):
|
||||
"""
|
||||
A class to model a filter component and its thermal emission. The model can be created from a file, the name of
|
||||
a band or a custom spectral range.
|
||||
"""
|
||||
_band_central_wl = dict(U=366 * u.nm, B=438 * u.nm, V=545 * u.nm, R=641 * u.nm, I=798 * u.nm, J=1220 * u.nm,
|
||||
H=1630 * u.nm, K=2190 * u.nm)
|
||||
_band_bandwidth = dict(U=68 * u.nm, B=98 * u.nm, V=89 * u.nm, R=220 * u.nm, I=240 * u.nm, J=300 * u.nm, H=400 * u.nm,
|
||||
K=600 * u.nm)
|
||||
|
||||
@u.quantity_input(temp=[u.Kelvin, u.Celsius], obstructor_temp=[u.Kelvin, u.Celsius])
|
||||
def __init__(self, parent: ITransmissive, transmittance: Union[SpectralQty, Callable],
|
||||
emissivity: Union[SpectralQty, int, float] = 1, temp: u.Quantity = 0 * u.K, obstruction: float = 0,
|
||||
obstructor_temp: u.Quantity = 0 * u.K, obstructor_emissivity: float = 1):
|
||||
"""
|
||||
Instantiate a new filter model
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parent : ITransmissive
|
||||
The parent element of the optical component from which the electromagnetic radiation is received.
|
||||
transmittance : Union[SpectralQty, Callable]
|
||||
The spectral transmittance coefficients of the filter.
|
||||
emissivity : SpectralQty
|
||||
The spectral emissivity coefficient for the optical surface.
|
||||
temp: Quantity in Kelvin / Celsius
|
||||
Temperature of the optical component
|
||||
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.
|
||||
obstructor_temp : Quantity in Kelvin / Celsius
|
||||
Temperature of the obstructing component.
|
||||
obstructor_emissivity : float
|
||||
Emissivity of the obstructing component.
|
||||
"""
|
||||
super().__init__(parent, emissivity, temp, obstruction, obstructor_temp, obstructor_emissivity)
|
||||
self._transmittance = transmittance
|
||||
|
||||
@classmethod
|
||||
# @u.quantity_input(temp=[u.Kelvin, u.Celsius], obstructor_temp=[u.Kelvin, u.Celsius])
|
||||
def fromBand(cls, parent: ITransmissive, band: str, emissivity: Union[str, int, float] = 1,
|
||||
temp: u.Quantity = 0 * u.K, obstruction: float = 0, obstructor_temp: u.Quantity = 0 * u.K,
|
||||
obstructor_emissivity: float = 1) -> "Filter":
|
||||
"""
|
||||
Instantiate a new filter model from a spectral band. The filter will be modelled as bandpass filter of
|
||||
infinite order and therefore similar to a hat-function.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parent : ITransmissive
|
||||
The parent element of the optical component from which the electromagnetic radiation is received.
|
||||
band : str
|
||||
The spectral band of the filter. Can be one of [U, B, V, R, I, J, H, K].
|
||||
emissivity : SpectralQty
|
||||
The spectral emissivity coefficient for the optical surface.
|
||||
temp: Quantity in Kelvin / Celsius
|
||||
Temperature of the optical component
|
||||
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.
|
||||
obstructor_temp : Quantity in Kelvin / Celsius
|
||||
Temperature of the obstructing component.
|
||||
obstructor_emissivity : float
|
||||
Emissivity of the obstructing component.
|
||||
|
||||
Returns
|
||||
-------
|
||||
filter : Filter
|
||||
The instantiated filter object.
|
||||
"""
|
||||
if band not in cls._band_central_wl.keys():
|
||||
error("Band has to be one of '[" + ", ".join(list(cls._band_central_wl.keys())) + "]'")
|
||||
return cls.fromRange(parent, cls._band_central_wl[band] - cls._band_bandwidth[band] / 2,
|
||||
cls._band_central_wl[band] + cls._band_bandwidth[band] / 2, emissivity, temp, obstruction,
|
||||
obstructor_temp, obstructor_emissivity)
|
||||
|
||||
@classmethod
|
||||
# @u.quantity_input(temp=[u.Kelvin, u.Celsius], obstructor_temp=[u.Kelvin, u.Celsius])
|
||||
def fromFile(cls, parent: ITransmissive, transmittance: str, emissivity: Union[str, int, float] = 1,
|
||||
temp: u.Quantity = 0 * u.K, obstruction: float = 0, obstructor_temp: u.Quantity = 0 * u.K,
|
||||
obstructor_emissivity: float = 1) -> "Filter":
|
||||
"""
|
||||
Instantiate a new filter model from a file containing the spectral transmittance coefficients.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parent : ITransmissive
|
||||
The parent element of the optical component from which the electromagnetic radiation is received.
|
||||
transmittance : str
|
||||
Path to the file containing the spectral transmittance-coefficients of the filter element.
|
||||
The format of the file will be guessed by `astropy.io.ascii.read()`.
|
||||
emissivity : SpectralQty
|
||||
The spectral emissivity coefficient for the optical surface.
|
||||
temp: Quantity in Kelvin / Celsius
|
||||
Temperature of the optical component
|
||||
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.
|
||||
obstructor_temp : Quantity in Kelvin / Celsius
|
||||
Temperature of the obstructing component.
|
||||
obstructor_emissivity : float
|
||||
Emissivity of the obstructing component.
|
||||
|
||||
Returns
|
||||
-------
|
||||
filter : Filter
|
||||
The instantiated filter object.
|
||||
"""
|
||||
return cls(parent, SpectralQty.fromFile(transmittance, u.nm, u.dimensionless_unscaled), emissivity, temp,
|
||||
obstruction, obstructor_temp, obstructor_emissivity)
|
||||
|
||||
@classmethod
|
||||
# @u.quantity_input(start="length", end="length", temp=[u.Kelvin, u.Celsius], obstructor_temp=[u.Kelvin, u.Celsius])
|
||||
def fromRange(cls, parent: ITransmissive, start: u.Quantity, end: u.Quantity,
|
||||
emissivity: Union[str, int, float] = 1, temp: u.Quantity = 0 * u.K, obstruction: float = 0,
|
||||
obstructor_temp: u.Quantity = 0 * u.K, obstructor_emissivity: float = 1) -> "Filter":
|
||||
"""
|
||||
Instantiate a new filter model from a spectral range. The filter will be modelled as bandpass filter of
|
||||
infinite order and therefore similar to a hat-function.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parent : ITransmissive
|
||||
The parent element of the optical component from which the electromagnetic radiation is received.
|
||||
start : length-quantity
|
||||
Start wavelength of the pass-band
|
||||
end : length-quantity
|
||||
End wavelength of the pass-band
|
||||
emissivity : SpectralQty
|
||||
The spectral emissivity coefficient for the optical surface.
|
||||
temp: Quantity in Kelvin / Celsius
|
||||
Temperature of the optical component
|
||||
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.
|
||||
obstructor_temp : Quantity in Kelvin / Celsius
|
||||
Temperature of the obstructing component.
|
||||
obstructor_emissivity : float
|
||||
Emissivity of the obstructing component.
|
||||
|
||||
Returns
|
||||
-------
|
||||
filter : Filter
|
||||
The instantiated filter object.
|
||||
"""
|
||||
return cls(parent, cls._filter_factory(start, end), emissivity, temp,
|
||||
obstruction, obstructor_temp, obstructor_emissivity)
|
||||
|
||||
def propagate(self, sqty: SpectralQty) -> SpectralQty:
|
||||
"""
|
||||
Propagate incoming radiation through the optical component
|
||||
|
||||
Parameters
|
||||
----------
|
||||
sqty : SpectralQty
|
||||
The incoming radiation
|
||||
|
||||
Returns
|
||||
-------
|
||||
sqty : SpectralQty
|
||||
Manipulated incoming radiation
|
||||
"""
|
||||
return sqty * self._transmittance
|
||||
|
||||
@staticmethod
|
||||
# @u.quantity_input(start="length", end="length")
|
||||
def _filter_factory(start: u.Quantity, end: u.Quantity):
|
||||
"""
|
||||
Create a infinite order bandpass filter
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : length-quantity
|
||||
Start wavelength of the pass-band
|
||||
end : length-quantity
|
||||
End wavelength of the pass-band
|
||||
|
||||
Returns
|
||||
-------
|
||||
lambda : Callable
|
||||
The filter function
|
||||
"""
|
||||
return lambda wl: 1 * u.dimensionless_unscaled if start <= wl <= end else 0 * u.dimensionless_unscaled
|
@ -2,3 +2,4 @@ from esbo_etc.classes.optical_component.AOpticalComponent import *
|
||||
from esbo_etc.classes.optical_component.Atmosphere import *
|
||||
from esbo_etc.classes.optical_component.StrayLight import *
|
||||
from esbo_etc.classes.optical_component.AHotOpticalComponent import *
|
||||
from esbo_etc.classes.optical_component.Filter import *
|
||||
|
21
tests/test_Filter.py
Normal file
21
tests/test_Filter.py
Normal file
@ -0,0 +1,21 @@
|
||||
from unittest import TestCase
|
||||
from esbo_etc import Filter, BlackBodyTarget, FileTarget, SpectralQty
|
||||
import numpy as np
|
||||
import astropy.units as u
|
||||
|
||||
|
||||
class TestFilter(TestCase):
|
||||
def test_fromBand(self):
|
||||
wl = [400, 500, 501, 545, 589, 590, 600] << u.nm
|
||||
target = BlackBodyTarget(wl, temp=5778 * u.K, mag=10 * u.mag, band="U")
|
||||
filt = Filter.fromBand(target, "V")
|
||||
self.assertEqual(filt.calcSignal(), SpectralQty(wl, [0.0, 0.0, 5.46516556e-15, 5.37748512e-15, 5.15313966e-15,
|
||||
0.0, 0.0] << u.W / (u.m ** 2 * u.nm)))
|
||||
|
||||
def test_fromFile(self):
|
||||
target = FileTarget("data/target/target_demo_1.csv")
|
||||
filt = Filter.fromFile(target, "data/filter/filter_transmittance.csv")
|
||||
self.assertEqual(filt.calcSignal(), SpectralQty(np.arange(200, 210, 1) << u.nm,
|
||||
[1.10e-15, 1.20e-15, 1.30e-15, 1.40e-15, 1.35e-15, 1.44e-15,
|
||||
1.53e-15, 1.44e-15, 1.52e-15, 1.40e-15] << u.W / (
|
||||
u.m ** 2 * u.nm)))
|
Loading…
x
Reference in New Issue
Block a user