Parse ATRAN files
This commit is contained in:
parent
b8472c8dd0
commit
59c5cd8000
@ -2,7 +2,10 @@ from .AOpticalComponent import AOpticalComponent
|
|||||||
from ..IRadiant import IRadiant
|
from ..IRadiant import IRadiant
|
||||||
from ..SpectralQty import SpectralQty
|
from ..SpectralQty import SpectralQty
|
||||||
from ..Entry import Entry
|
from ..Entry import Entry
|
||||||
|
from ...lib.logger import logger
|
||||||
import astropy.units as u
|
import astropy.units as u
|
||||||
|
from astropy.io import ascii
|
||||||
|
from astropy.modeling.models import BlackBody
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
@ -11,7 +14,7 @@ class Atmosphere(AOpticalComponent):
|
|||||||
A class to model the atmosphere including the atmosphere's spectral transmittance and emission.
|
A class to model the atmosphere including the atmosphere's spectral transmittance and emission.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent: IRadiant, transmittance: str, emission: str = None):
|
def __init__(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize a new atmosphere model
|
Initialize a new atmosphere model
|
||||||
|
|
||||||
@ -27,18 +30,57 @@ class Atmosphere(AOpticalComponent):
|
|||||||
Path to the file containing the spectral radiance of the atmosphere.
|
Path to the file containing the spectral radiance of the atmosphere.
|
||||||
The format of the file will be guessed by `astropy.io.ascii.read()`.
|
The format of the file will be guessed by `astropy.io.ascii.read()`.
|
||||||
"""
|
"""
|
||||||
# Read the transmittance
|
|
||||||
transmittance_sqty = SpectralQty.fromFile(transmittance, wl_unit_default=u.nm,
|
args = dict()
|
||||||
qty_unit_default=u.dimensionless_unscaled)
|
if "temp" in kwargs:
|
||||||
if emission is None:
|
args = self._fromATRAN(**kwargs)
|
||||||
# No emission is given, initialize the super class
|
elif "transmittance" in kwargs:
|
||||||
super().__init__(parent, transmittance_sqty, 0)
|
args = self._fromFiles(**kwargs)
|
||||||
else:
|
else:
|
||||||
# Read the emission
|
logger.error("Wrong parameters for class Atmosphere.")
|
||||||
emission_sqty = SpectralQty.fromFile(emission, wl_unit_default=u.nm,
|
super().__init__(parent=args["parent"], transreflectivity=args["transmittance"], noise=args["emission"])
|
||||||
qty_unit_default=u.W / (u.m ** 2 * u.nm * u.sr))
|
|
||||||
# Initialize the super class
|
def _fromFiles(self, parent: IRadiant, transmittance: str, emission: str = None):
|
||||||
super().__init__(parent, transmittance_sqty, emission_sqty)
|
"""
|
||||||
|
Initialize a new atmosphere model from two files
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
parent : IRadiant
|
||||||
|
The parent element of the atmosphere from which the electromagnetic radiation is received.
|
||||||
|
This element is usually of type Target or StrayLight.
|
||||||
|
transmittance : str
|
||||||
|
Path to the file containing the spectral transmittance-coefficients of the atmosphere.
|
||||||
|
The format of the file will be guessed by `astropy.io.ascii.read()`.
|
||||||
|
emission : str
|
||||||
|
Path to the file containing the spectral radiance of the atmosphere.
|
||||||
|
The format of the file will be guessed by `astropy.io.ascii.read()`.
|
||||||
|
"""
|
||||||
|
# Read the transmittance
|
||||||
|
transmittance = SpectralQty.fromFile(transmittance, wl_unit_default=u.nm,
|
||||||
|
qty_unit_default=u.dimensionless_unscaled)
|
||||||
|
if emission is None:
|
||||||
|
emission = 0
|
||||||
|
else:
|
||||||
|
emission = SpectralQty.fromFile(emission, wl_unit_default=u.nm,
|
||||||
|
qty_unit_default=u.W / (u.m ** 2 * u.nm * u.sr))
|
||||||
|
return {"parent": parent, "transmittance": transmittance, "emission": emission}
|
||||||
|
|
||||||
|
def _fromATRAN(self, parent: IRadiant, transmittance: str, temp: u.Quantity):
|
||||||
|
transmittance = "data_sofia/atmospheric_transmittance.dat"
|
||||||
|
# Read the file
|
||||||
|
data = ascii.read(transmittance, format=None)
|
||||||
|
# Set units
|
||||||
|
data["col2"].unit = u.um
|
||||||
|
data["col3"].unit = u.dimensionless_unscaled
|
||||||
|
# Create spectral quantity
|
||||||
|
transmittance = SpectralQty(data["col2"].quantity, data["col3"].quantity)
|
||||||
|
|
||||||
|
# Create black body
|
||||||
|
bb = self.__gb_factory(temp)
|
||||||
|
# Calculate emission
|
||||||
|
emission = SpectralQty(transmittance.wl, bb(transmittance.wl)) * transmittance
|
||||||
|
return {"parent": parent, "transmittance": transmittance, "emission": emission}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_config(conf: Entry) -> Union[None, str]:
|
def check_config(conf: Entry) -> Union[None, str]:
|
||||||
@ -62,3 +104,24 @@ class Atmosphere(AOpticalComponent):
|
|||||||
mes = conf.check_file("emission")
|
mes = conf.check_file("emission")
|
||||||
if mes is not None:
|
if mes is not None:
|
||||||
return mes
|
return mes
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@u.quantity_input(temp=[u.Kelvin, u.Celsius])
|
||||||
|
def __gb_factory(temp: u.Quantity, em: Union[int, float] = 1):
|
||||||
|
"""
|
||||||
|
Factory for a grey body lambda-function.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
temp : Quantity in Kelvin / Celsius
|
||||||
|
The temperature fo the grey body.
|
||||||
|
em : Union[int, float]
|
||||||
|
Emissivity of the the grey body
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
bb : Callable
|
||||||
|
The lambda function for the grey body.
|
||||||
|
"""
|
||||||
|
bb = BlackBody(temperature=temp, scale=em * u.W / (u.m ** 2 * u.nm * u.sr))
|
||||||
|
return lambda wl: bb(wl)
|
||||||
|
@ -7,8 +7,9 @@ import astropy.units as u
|
|||||||
class TestAtmosphere(TestCase):
|
class TestAtmosphere(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.target = FileTarget("tests/data/target/target_demo_1.csv", np.arange(200, 208) << u.nm)
|
self.target = FileTarget("tests/data/target/target_demo_1.csv", np.arange(200, 208) << u.nm)
|
||||||
self.atmosphere = Atmosphere(self.target, "tests/data/atmosphere/atmosphere_transmittance_1.csv",
|
self.atmosphere = Atmosphere(parent=self.target,
|
||||||
"tests/data/atmosphere/atmosphere_emission_1.csv")
|
transmittance="tests/data/atmosphere/atmosphere_transmittance_1.csv",
|
||||||
|
emission="tests/data/atmosphere/atmosphere_emission_1.csv")
|
||||||
|
|
||||||
def test_calcSignal(self):
|
def test_calcSignal(self):
|
||||||
self.assertEqual(self.atmosphere.calcSignal()[0],
|
self.assertEqual(self.atmosphere.calcSignal()[0],
|
||||||
@ -16,7 +17,7 @@ class TestAtmosphere(TestCase):
|
|||||||
np.array([1.10e-15, 1.20e-15, 1.30e-15, 1.26e-15, 1.20e-15, 1.12e-15, 1.02e-15,
|
np.array([1.10e-15, 1.20e-15, 1.30e-15, 1.26e-15, 1.20e-15, 1.12e-15, 1.02e-15,
|
||||||
0.9e-15]) << u.W / (u.m ** 2 * u.nm)))
|
0.9e-15]) << u.W / (u.m ** 2 * u.nm)))
|
||||||
|
|
||||||
def test_calcBackgrounde(self):
|
def test_calcBackground(self):
|
||||||
self.assertEqual(self.atmosphere.calcBackground(),
|
self.assertEqual(self.atmosphere.calcBackground(),
|
||||||
SpectralQty(np.arange(200, 208) << u.nm,
|
SpectralQty(np.arange(200, 208) << u.nm,
|
||||||
np.array([1.1e-16, 1.2e-16, 1.3e-16, 1.4e-16, 1.5e-16, 1.6e-16, 1.7e-16,
|
np.array([1.1e-16, 1.2e-16, 1.3e-16, 1.4e-16, 1.5e-16, 1.6e-16, 1.7e-16,
|
||||||
|
@ -17,7 +17,7 @@ class TestHeterodyne(TestCase):
|
|||||||
receiver_temp=1050 * u.K, eta_fss=0.97, lambda_line=157.774 * u.um, kappa=1.0,
|
receiver_temp=1050 * u.K, eta_fss=0.97, lambda_line=157.774 * u.um, kappa=1.0,
|
||||||
common_conf=self.config.common)
|
common_conf=self.config.common)
|
||||||
self.target = FileTarget("tests/data/target/line.csv", self.config.common.wl_bins())
|
self.target = FileTarget("tests/data/target/line.csv", self.config.common.wl_bins())
|
||||||
self.atmosphere = Atmosphere(self.target, "tests/data/atmosphere/transmittance_great.csv")
|
self.atmosphere = Atmosphere(parent=self.target, transmittance="tests/data/atmosphere/transmittance_great.csv")
|
||||||
self.cosmic = CosmicBackground(self.atmosphere, temp=220 * u.K, emissivity=0.14)
|
self.cosmic = CosmicBackground(self.atmosphere, temp=220 * u.K, emissivity=0.14)
|
||||||
self.mirror = Mirror(self.cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08,
|
self.mirror = Mirror(self.cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08,
|
||||||
temp=230 * u.K)
|
temp=230 * u.K)
|
||||||
@ -36,13 +36,13 @@ class TestHeterodyne(TestCase):
|
|||||||
def test_getSensitivity(self):
|
def test_getSensitivity(self):
|
||||||
exp_time = 1900 * u.s
|
exp_time = 1900 * u.s
|
||||||
target = BlackBodyTarget(self.config.common.wl_bins(), mag=20 * u.mag)
|
target = BlackBodyTarget(self.config.common.wl_bins(), mag=20 * u.mag)
|
||||||
atmosphere = Atmosphere(target, "tests/data/atmosphere/transmittance_great.csv")
|
atmosphere = Atmosphere(parent=target, transmittance="tests/data/atmosphere/transmittance_great.csv")
|
||||||
cosmic = CosmicBackground(atmosphere, temp=220 * u.K, emissivity=0.14)
|
cosmic = CosmicBackground(atmosphere, temp=220 * u.K, emissivity=0.14)
|
||||||
mirror = Mirror(cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08, temp=230 * u.K)
|
mirror = Mirror(cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08, temp=230 * u.K)
|
||||||
heterodyne = Heterodyne(mirror, **self.heterodyne_args)
|
heterodyne = Heterodyne(mirror, **self.heterodyne_args)
|
||||||
snr = heterodyne.getSNR(exp_time)
|
snr = heterodyne.getSNR(exp_time)
|
||||||
target = BlackBodyTarget(self.config.common.wl_bins(), mag=10 * u.mag)
|
target = BlackBodyTarget(self.config.common.wl_bins(), mag=10 * u.mag)
|
||||||
atmosphere = Atmosphere(target, "tests/data/atmosphere/transmittance_great.csv")
|
atmosphere = Atmosphere(parent=target, transmittance="tests/data/atmosphere/transmittance_great.csv")
|
||||||
cosmic = CosmicBackground(atmosphere, temp=220 * u.K, emissivity=0.14)
|
cosmic = CosmicBackground(atmosphere, temp=220 * u.K, emissivity=0.14)
|
||||||
mirror = Mirror(cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08, temp=230 * u.K)
|
mirror = Mirror(cosmic, reflectance="tests/data/mirror/reflectance_great.csv", emissivity=0.08, temp=230 * u.K)
|
||||||
heterodyne = Heterodyne(mirror, **self.heterodyne_args)
|
heterodyne = Heterodyne(mirror, **self.heterodyne_args)
|
||||||
|
@ -16,8 +16,8 @@ class TestRadiantFactory(TestCase):
|
|||||||
parent = oc_factory.fromConfigBatch(conf, parent)
|
parent = oc_factory.fromConfigBatch(conf, parent)
|
||||||
|
|
||||||
parent_2 = BlackBodyTarget(conf.common.wl_bins(), 5778 * u.K, 10 * u.mag, "V")
|
parent_2 = BlackBodyTarget(conf.common.wl_bins(), 5778 * u.K, 10 * u.mag, "V")
|
||||||
parent_2 = oc.Atmosphere(parent_2, "tests/data/atmosphere/transmittance.csv",
|
parent_2 = oc.Atmosphere(parent=parent_2, transmittance="tests/data/atmosphere/transmittance.csv",
|
||||||
"tests/data/atmosphere/emission.csv")
|
emission="tests/data/atmosphere/emission.csv")
|
||||||
parent_2 = oc.StrayLight(parent_2, "tests/data/straylight/emission.csv")
|
parent_2 = oc.StrayLight(parent_2, "tests/data/straylight/emission.csv")
|
||||||
parent_2 = oc.Mirror(parent_2, "tests/data/mirror/reflectance.csv",
|
parent_2 = oc.Mirror(parent_2, "tests/data/mirror/reflectance.csv",
|
||||||
"tests/data/mirror/emissivity.csv", 70 * u.K, obstruction=0.1, obstructor_temp=70 * u.K)
|
"tests/data/mirror/emissivity.csv", 70 * u.K, obstruction=0.1, obstructor_temp=70 * u.K)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user