Parse ATRAN files

This commit is contained in:
Lukas Klass 2020-09-30 21:53:09 +02:00
parent b8472c8dd0
commit 59c5cd8000
4 changed files with 84 additions and 20 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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)