call to parent object moved to ASensor
This commit is contained in:
parent
0f803a3484
commit
02b3ed2f73
@ -3,6 +3,8 @@ import astropy.units as u
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from ..Entry import Entry
|
from ..Entry import Entry
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
from ..SpectralQty import SpectralQty
|
||||||
|
from ...lib.logger import logger
|
||||||
|
|
||||||
|
|
||||||
class ASensor:
|
class ASensor:
|
||||||
@ -21,7 +23,25 @@ class ASensor:
|
|||||||
"""
|
"""
|
||||||
self._parent = parent
|
self._parent = parent
|
||||||
|
|
||||||
@abstractmethod
|
def __calcIncomingRadiation(self):
|
||||||
|
"""
|
||||||
|
Trigger the radiation transportation pipeline in order to calculate the received radiation.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
"""
|
||||||
|
logger.info("Calculating incoming background radiation", extra={"spinning": True})
|
||||||
|
background = self._parent.calcBackground()
|
||||||
|
logger.info("Calculating incoming signal radiation", extra={"spinning": True})
|
||||||
|
signal, obstruction = self._parent.calcSignal()
|
||||||
|
return background, signal, obstruction
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time")
|
@u.quantity_input(exp_time="time")
|
||||||
def getSNR(self, exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
def getSNR(self, exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
||||||
"""
|
"""
|
||||||
@ -37,9 +57,34 @@ class ASensor:
|
|||||||
snr : Quantity
|
snr : Quantity
|
||||||
The calculated SNR
|
The calculated SNR
|
||||||
"""
|
"""
|
||||||
pass
|
background, signal, obstruction = self.__calcIncomingRadiation()
|
||||||
|
return self.calcSNR(background, signal, obstruction, exp_time)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@u.quantity_input(exp_time="time")
|
||||||
|
def calcSNR(self, background: SpectralQty, signal: SpectralQty, obstruction: float,
|
||||||
|
exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
||||||
|
"""
|
||||||
|
Calculate the signal to noise ratio (SNR) for the given exposure time.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
exp_time : time-Quantity
|
||||||
|
The exposure time to calculate the SNR for.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
snr : Quantity
|
||||||
|
The calculated SNR
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@u.quantity_input(snr=u.dimensionless_unscaled)
|
@u.quantity_input(snr=u.dimensionless_unscaled)
|
||||||
def getExpTime(self, snr: u.Quantity) -> u.s:
|
def getExpTime(self, snr: u.Quantity) -> u.s:
|
||||||
"""
|
"""
|
||||||
@ -55,9 +100,33 @@ class ASensor:
|
|||||||
exp_time : Quantity
|
exp_time : Quantity
|
||||||
The necessary exposure time in seconds.
|
The necessary exposure time in seconds.
|
||||||
"""
|
"""
|
||||||
pass
|
background, signal, obstruction = self.__calcIncomingRadiation()
|
||||||
|
return self.calcExpTime(background, signal, obstruction, snr)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@u.quantity_input(snr=u.dimensionless_unscaled)
|
||||||
|
def calcExpTime(self, background: SpectralQty, signal: SpectralQty, obstruction: float, snr: u.Quantity) -> u.s:
|
||||||
|
"""
|
||||||
|
Calculate the necessary exposure time in order to achieve the given SNR.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
snr : Quantity
|
||||||
|
The SNR for which the necessary exposure time shall be calculated.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
exp_time : Quantity
|
||||||
|
The necessary exposure time in seconds.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
||||||
def getSensitivity(self, exp_time: u.Quantity, snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
def getSensitivity(self, exp_time: u.Quantity, snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
||||||
"""
|
"""
|
||||||
@ -72,6 +141,36 @@ class ASensor:
|
|||||||
target_brightness : Quantity
|
target_brightness : Quantity
|
||||||
The target brightness in magnitudes.
|
The target brightness in magnitudes.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
sensitivity: Quantity
|
||||||
|
The sensitivity as limiting apparent star magnitude in mag.
|
||||||
|
"""
|
||||||
|
background, signal, obstruction = self.__calcIncomingRadiation()
|
||||||
|
return self.calcSensitivity(background, signal, obstruction, exp_time, snr, target_brightness)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
||||||
|
def calcSensitivity(self, background: SpectralQty, signal: SpectralQty, obstruction: float, exp_time: u.Quantity,
|
||||||
|
snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
||||||
|
"""
|
||||||
|
Calculate the sensitivity of the telescope detector combination.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
exp_time : Quantity
|
||||||
|
The exposure time in seconds.
|
||||||
|
snr : Quantity
|
||||||
|
The SNR for which the sensitivity time shall be calculated.
|
||||||
|
target_brightness : Quantity
|
||||||
|
The target brightness in magnitudes.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
sensitivity: Quantity
|
sensitivity: Quantity
|
||||||
|
@ -6,6 +6,7 @@ import numpy as np
|
|||||||
from astropy.constants import k_B
|
from astropy.constants import k_B
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from ...lib.logger import logger
|
from ...lib.logger import logger
|
||||||
|
from ..SpectralQty import SpectralQty
|
||||||
|
|
||||||
|
|
||||||
class Heterodyne(ASensor):
|
class Heterodyne(ASensor):
|
||||||
@ -51,12 +52,19 @@ class Heterodyne(ASensor):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time")
|
@u.quantity_input(exp_time="time")
|
||||||
def getSNR(self, exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
def calcSNR(self, background: SpectralQty, signal: SpectralQty, obstruction: float,
|
||||||
|
exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
||||||
"""
|
"""
|
||||||
Calculate the signal to background ratio (SNR) for the given exposure time using the CCD-equation.
|
Calculate the signal to background ratio (SNR) for the given exposure time using the CCD-equation.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
exp_time : time-Quantity
|
exp_time : time-Quantity
|
||||||
The exposure time to calculate the SNR for.
|
The exposure time to calculate the SNR for.
|
||||||
|
|
||||||
@ -66,7 +74,7 @@ class Heterodyne(ASensor):
|
|||||||
The calculated SNR as dimensionless quantity
|
The calculated SNR as dimensionless quantity
|
||||||
"""
|
"""
|
||||||
# Calculate the signal and background temperatures
|
# Calculate the signal and background temperatures
|
||||||
t_signal, t_background = self.calcTemperatures()
|
t_signal, t_background = self.calcTemperatures(background, signal, obstruction)
|
||||||
t_sys = 2 * (t_background + self.__receiver_temp)
|
t_sys = 2 * (t_background + self.__receiver_temp)
|
||||||
# Calculate the noise bandwidth
|
# Calculate the noise bandwidth
|
||||||
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
||||||
@ -87,12 +95,18 @@ class Heterodyne(ASensor):
|
|||||||
return snr
|
return snr
|
||||||
|
|
||||||
@u.quantity_input(snr=u.dimensionless_unscaled)
|
@u.quantity_input(snr=u.dimensionless_unscaled)
|
||||||
def getExpTime(self, snr: u.Quantity) -> u.s:
|
def calcExpTime(self, background: SpectralQty, signal: SpectralQty, obstruction: float, snr: u.Quantity) -> u.s:
|
||||||
"""
|
"""
|
||||||
Calculate the necessary exposure time in order to achieve the given SNR.
|
Calculate the necessary exposure time in order to achieve the given SNR.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
snr : Quantity
|
snr : Quantity
|
||||||
The SNR for which the necessary exposure time shall be calculated as dimensionless quantity.
|
The SNR for which the necessary exposure time shall be calculated as dimensionless quantity.
|
||||||
|
|
||||||
@ -102,7 +116,7 @@ class Heterodyne(ASensor):
|
|||||||
The necessary exposure time in seconds.
|
The necessary exposure time in seconds.
|
||||||
"""
|
"""
|
||||||
# Calculate the signal and background temperatures
|
# Calculate the signal and background temperatures
|
||||||
t_signal, t_background = self.calcTemperatures()
|
t_signal, t_background = self.calcTemperatures(background, signal, obstruction)
|
||||||
t_sys = 2 * (t_background + self.__receiver_temp)
|
t_sys = 2 * (t_background + self.__receiver_temp)
|
||||||
# Calculate the noise bandwidth
|
# Calculate the noise bandwidth
|
||||||
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
||||||
@ -123,12 +137,19 @@ class Heterodyne(ASensor):
|
|||||||
return exp_time
|
return exp_time
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
||||||
def getSensitivity(self, exp_time: u.Quantity, snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
def calcSensitivity(self, background: SpectralQty, signal: SpectralQty, obstruction: float, exp_time: u.Quantity,
|
||||||
|
snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
||||||
"""
|
"""
|
||||||
Calculate the sensitivity of the telescope detector combination.
|
Calculate the sensitivity of the telescope detector combination.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
exp_time : Quantity
|
exp_time : Quantity
|
||||||
The exposure time in seconds.
|
The exposure time in seconds.
|
||||||
snr : Quantity
|
snr : Quantity
|
||||||
@ -142,7 +163,7 @@ class Heterodyne(ASensor):
|
|||||||
The sensitivity as limiting apparent star magnitude in mag.
|
The sensitivity as limiting apparent star magnitude in mag.
|
||||||
"""
|
"""
|
||||||
# Calculate the signal and background temperatures
|
# Calculate the signal and background temperatures
|
||||||
t_signal, t_background = self.calcTemperatures()
|
t_signal, t_background = self.calcTemperatures(background, signal, obstruction)
|
||||||
t_sys = 2 * (t_background + self.__receiver_temp)
|
t_sys = 2 * (t_background + self.__receiver_temp)
|
||||||
# Calculate the noise bandwidth
|
# Calculate the noise bandwidth
|
||||||
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
delta_nu = self.__lambda_line.to(u.Hz, equivalencies=u.spectral()) / (
|
||||||
@ -193,10 +214,19 @@ class Heterodyne(ASensor):
|
|||||||
logger.info(prefix + "Antenna temperature: %1.2e K" % t_signal.value)
|
logger.info(prefix + "Antenna temperature: %1.2e K" % t_signal.value)
|
||||||
logger.info("-------------------------------------------------------------------------------------------------")
|
logger.info("-------------------------------------------------------------------------------------------------")
|
||||||
|
|
||||||
def calcTemperatures(self):
|
def calcTemperatures(self, background: SpectralQty, signal: SpectralQty, obstruction: float):
|
||||||
"""
|
"""
|
||||||
Calculate the noise temperatures of the signal and the background radiation.
|
Calculate the noise temperatures of the signal and the background radiation.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
t_signal : u.Quantity
|
t_signal : u.Quantity
|
||||||
@ -205,12 +235,11 @@ class Heterodyne(ASensor):
|
|||||||
The background temperature in Kelvins.
|
The background temperature in Kelvins.
|
||||||
"""
|
"""
|
||||||
logger.info("Calculating the system temperature.")
|
logger.info("Calculating the system temperature.")
|
||||||
t_background = (self._parent.calcBackground().rebin(self.__lambda_line).qty.to(
|
t_background = (background.rebin(self.__lambda_line).qty.to(
|
||||||
u.W / (u.m ** 2 * u.Hz * u.sr), equivalencies=u.spectral_density(self.__lambda_line)) *
|
u.W / (u.m ** 2 * u.Hz * u.sr), equivalencies=u.spectral_density(self.__lambda_line)) *
|
||||||
self.__lambda_line ** 2 / (2 * k_B) * u.sr).decompose()
|
self.__lambda_line ** 2 / (2 * k_B) * u.sr).decompose()
|
||||||
# Calculate the incoming photon current of the target
|
# Calculate the incoming photon current of the target
|
||||||
logger.info("Calculating the signal temperature.")
|
logger.info("Calculating the signal temperature.")
|
||||||
signal, obstruction = self._parent.calcSignal()
|
|
||||||
size = "extended" if signal.qty.unit.is_equivalent(u.W / (u.m ** 2 * u.nm * u.sr)) else "point"
|
size = "extended" if signal.qty.unit.is_equivalent(u.W / (u.m ** 2 * u.nm * u.sr)) else "point"
|
||||||
if size == "point":
|
if size == "point":
|
||||||
signal = signal.rebin(self.__lambda_line).qty.to(u.W / (u.m ** 2 * u.Hz),
|
signal = signal.rebin(self.__lambda_line).qty.to(u.W / (u.m ** 2 * u.Hz),
|
||||||
|
@ -93,12 +93,19 @@ class Imager(ASensor):
|
|||||||
common_conf.psf.osf, pixel_size)
|
common_conf.psf.osf, pixel_size)
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time")
|
@u.quantity_input(exp_time="time")
|
||||||
def getSNR(self, exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
def calcSNR(self, background: SpectralQty, signal: SpectralQty, obstruction: float,
|
||||||
|
exp_time: u.Quantity) -> u.dimensionless_unscaled:
|
||||||
"""
|
"""
|
||||||
Calculate the signal to background ratio (SNR) for the given exposure time using the CCD-equation.
|
Calculate the signal to background ratio (SNR) for the given exposure time using the CCD-equation.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
exp_time : time-Quantity
|
exp_time : time-Quantity
|
||||||
The exposure time to calculate the SNR for.
|
The exposure time to calculate the SNR for.
|
||||||
|
|
||||||
@ -108,7 +115,8 @@ class Imager(ASensor):
|
|||||||
The calculated SNR as dimensionless quantity
|
The calculated SNR as dimensionless quantity
|
||||||
"""
|
"""
|
||||||
# Calculate the electron currents
|
# Calculate the electron currents
|
||||||
signal_current, background_current, read_noise, dark_current = self.__exposePixels()
|
signal_current, background_current, read_noise, dark_current = self.__exposePixels(background, signal,
|
||||||
|
obstruction)
|
||||||
# Calculate the SNR using the CCD-equation
|
# Calculate the SNR using the CCD-equation
|
||||||
logger.info("Calculating the SNR...", extra={"spinning": True})
|
logger.info("Calculating the SNR...", extra={"spinning": True})
|
||||||
snr = signal_current.sum() * exp_time / np.sqrt(
|
snr = signal_current.sum() * exp_time / np.sqrt(
|
||||||
@ -123,12 +131,18 @@ class Imager(ASensor):
|
|||||||
return snr.value * u.dimensionless_unscaled
|
return snr.value * u.dimensionless_unscaled
|
||||||
|
|
||||||
@u.quantity_input(snr=u.dimensionless_unscaled)
|
@u.quantity_input(snr=u.dimensionless_unscaled)
|
||||||
def getExpTime(self, snr: u.Quantity) -> u.s:
|
def calcExpTime(self, background: SpectralQty, signal: SpectralQty, obstruction: float, snr: u.Quantity) -> u.s:
|
||||||
"""
|
"""
|
||||||
Calculate the necessary exposure time in order to achieve the given SNR.
|
Calculate the necessary exposure time in order to achieve the given SNR.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
snr : Quantity
|
snr : Quantity
|
||||||
The SNR for which the necessary exposure time shall be calculated as dimensionless quantity.
|
The SNR for which the necessary exposure time shall be calculated as dimensionless quantity.
|
||||||
|
|
||||||
@ -138,7 +152,8 @@ class Imager(ASensor):
|
|||||||
The necessary exposure time in seconds.
|
The necessary exposure time in seconds.
|
||||||
"""
|
"""
|
||||||
# Calculate the electron currents
|
# Calculate the electron currents
|
||||||
signal_current, background_current, read_noise, dark_current = self.__exposePixels()
|
signal_current, background_current, read_noise, dark_current = self.__exposePixels(background, signal,
|
||||||
|
obstruction)
|
||||||
logger.info("Calculating the exposure time...", extra={"spinning": True})
|
logger.info("Calculating the exposure time...", extra={"spinning": True})
|
||||||
# Calculate the electron currents for all pixels
|
# Calculate the electron currents for all pixels
|
||||||
signal_current_tot = signal_current.sum()
|
signal_current_tot = signal_current.sum()
|
||||||
@ -160,12 +175,19 @@ class Imager(ASensor):
|
|||||||
return exp_time
|
return exp_time
|
||||||
|
|
||||||
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
@u.quantity_input(exp_time="time", snr=u.dimensionless_unscaled, target_brightness=u.mag)
|
||||||
def getSensitivity(self, exp_time: u.Quantity, snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
def calcSensitivity(self, background: SpectralQty, signal: SpectralQty, obstruction: float, exp_time: u.Quantity,
|
||||||
|
snr: u.Quantity, target_brightness: u.Quantity) -> u.mag:
|
||||||
"""
|
"""
|
||||||
Calculate the sensitivity of the telescope detector combination.
|
Calculate the sensitivity of the telescope detector combination.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
exp_time : Quantity
|
exp_time : Quantity
|
||||||
The exposure time in seconds.
|
The exposure time in seconds.
|
||||||
snr : Quantity
|
snr : Quantity
|
||||||
@ -179,7 +201,8 @@ class Imager(ASensor):
|
|||||||
The sensitivity as limiting apparent star magnitude in mag.
|
The sensitivity as limiting apparent star magnitude in mag.
|
||||||
"""
|
"""
|
||||||
# Calculate the electron currents
|
# Calculate the electron currents
|
||||||
signal_current, background_current, read_noise, dark_current = self.__exposePixels()
|
signal_current, background_current, read_noise, dark_current = self.__exposePixels(background, signal,
|
||||||
|
obstruction)
|
||||||
logger.info("Calculating the sensitivity...", extra={"spinning": True})
|
logger.info("Calculating the sensitivity...", extra={"spinning": True})
|
||||||
# Fix the physical units of the SNR
|
# Fix the physical units of the SNR
|
||||||
snr = snr * u.electron ** 0.5
|
snr = snr * u.electron ** 0.5
|
||||||
@ -299,10 +322,20 @@ class Imager(ASensor):
|
|||||||
hdul = fits.HDUList([hdu, signal_hdu, background_hdu, read_noise_hdu, dark_hdu])
|
hdul = fits.HDUList([hdu, signal_hdu, background_hdu, read_noise_hdu, dark_hdu])
|
||||||
hdul.writeto(os.path.join(path, "results.fits"), overwrite=True)
|
hdul.writeto(os.path.join(path, "results.fits"), overwrite=True)
|
||||||
|
|
||||||
def __exposePixels(self) -> Tuple[u.Quantity, u.Quantity, u.Quantity, u.Quantity]:
|
def __exposePixels(self, background: SpectralQty, signal: SpectralQty,
|
||||||
|
obstruction: float) -> Tuple[u.Quantity, u.Quantity, u.Quantity, u.Quantity]:
|
||||||
"""
|
"""
|
||||||
Expose the pixels and calculate the signal and noise electron currents per pixel.
|
Expose the pixels and calculate the signal and noise electron currents per pixel.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
signal_current : Quantity
|
signal_current : Quantity
|
||||||
@ -316,7 +349,8 @@ class Imager(ASensor):
|
|||||||
"""
|
"""
|
||||||
# Calculate the total incoming electron current
|
# Calculate the total incoming electron current
|
||||||
logger.info("Calculating incoming electron current...", extra={"spinning": True})
|
logger.info("Calculating incoming electron current...", extra={"spinning": True})
|
||||||
signal_current, size, obstruction, background_current = self.__calcIncomingElectronCurrent()
|
signal_current, size, obstruction, background_current = self.__calcIncomingElectronCurrent(background, signal,
|
||||||
|
obstruction)
|
||||||
# info("Finished calculating incoming electron current", extra={"spinning": False})
|
# info("Finished calculating incoming electron current", extra={"spinning": False})
|
||||||
# Initialize a new PixelMask
|
# Initialize a new PixelMask
|
||||||
mask = PixelMask(self.__pixel_geometry, self.__pixel_size, self.__center_offset)
|
mask = PixelMask(self.__pixel_geometry, self.__pixel_size, self.__center_offset)
|
||||||
@ -354,11 +388,13 @@ class Imager(ASensor):
|
|||||||
logger.info("The radius of the photometric aperture is %.2f pixels. This equals the FWHM" % (
|
logger.info("The radius of the photometric aperture is %.2f pixels. This equals the FWHM" % (
|
||||||
d_photometric_ap.value / 2))
|
d_photometric_ap.value / 2))
|
||||||
elif self.__contained_energy.lower() == "min":
|
elif self.__contained_energy.lower() == "min":
|
||||||
logger.info("The radius of the photometric aperture is %.2f pixels. This equals the first minimum" % (
|
logger.info(
|
||||||
|
"The radius of the photometric aperture is %.2f pixels. This equals the first minimum" % (
|
||||||
d_photometric_ap.value / 2))
|
d_photometric_ap.value / 2))
|
||||||
else:
|
else:
|
||||||
logger.info("The radius of the photometric aperture is %.2f pixels. This equals %.0f%% encircled energy" %
|
logger.info(
|
||||||
(d_photometric_ap.value / 2, self.__contained_energy))
|
"The radius of the photometric aperture is %.2f pixels. This equals %.0f%% encircled energy" % (
|
||||||
|
d_photometric_ap.value / 2, self.__contained_energy))
|
||||||
logger.info("The photometric aperture contains " + str(np.count_nonzero(mask)) + " pixels.")
|
logger.info("The photometric aperture contains " + str(np.count_nonzero(mask)) + " pixels.")
|
||||||
if size.lower() != "extended":
|
if size.lower() != "extended":
|
||||||
# Map the PSF onto the pixel mask in order to get the relative irradiance of each pixel
|
# Map the PSF onto the pixel mask in order to get the relative irradiance of each pixel
|
||||||
@ -399,10 +435,20 @@ class Imager(ASensor):
|
|||||||
d_photometric_ap = observation_angle / pixel_fov
|
d_photometric_ap = observation_angle / pixel_fov
|
||||||
return d_photometric_ap * u.pix
|
return d_photometric_ap * u.pix
|
||||||
|
|
||||||
def __calcIncomingElectronCurrent(self) -> Tuple[u.Quantity, str, float, u.Quantity]:
|
def __calcIncomingElectronCurrent(self, background: SpectralQty, signal: SpectralQty,
|
||||||
|
obstruction: float) -> Tuple[u.Quantity, str, float, u.Quantity]:
|
||||||
"""
|
"""
|
||||||
Calculate the detected electron current of the signal and the background.
|
Calculate the detected electron current of the signal and the background.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
background : SpectralQty
|
||||||
|
The received background radiation
|
||||||
|
signal : SpectralQty
|
||||||
|
The received signal radiation
|
||||||
|
obstruction : float
|
||||||
|
The obstruction factor of the aperture as ratio A_ob / A_ap
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
signal_current : Quantity
|
signal_current : Quantity
|
||||||
@ -416,11 +462,10 @@ class Imager(ASensor):
|
|||||||
"""
|
"""
|
||||||
# Calculate the photon current of the background
|
# Calculate the photon current of the background
|
||||||
logger.info("Calculating the background photon current.")
|
logger.info("Calculating the background photon current.")
|
||||||
background_photon_current = self._parent.calcBackground() * np.pi * (
|
background_photon_current = background * np.pi * (
|
||||||
self.__pixel_size.to(u.m) ** 2 / u.pix) / (4 * self.__f_number ** 2 + 1) * (1 * u.sr)
|
self.__pixel_size.to(u.m) ** 2 / u.pix) / (4 * self.__f_number ** 2 + 1) * (1 * u.sr)
|
||||||
# Calculate the incoming photon current of the target
|
# Calculate the incoming photon current of the target
|
||||||
logger.info("Calculating the signal photon current.")
|
logger.info("Calculating the signal photon current.")
|
||||||
signal, obstruction = self._parent.calcSignal()
|
|
||||||
size = "extended" if signal.qty.unit.is_equivalent(u.W / (u.m ** 2 * u.nm * u.sr)) else "point"
|
size = "extended" if signal.qty.unit.is_equivalent(u.W / (u.m ** 2 * u.nm * u.sr)) else "point"
|
||||||
if size == "point":
|
if size == "point":
|
||||||
signal_photon_current = signal * np.pi * (self.__common_conf.d_aperture() / 2) ** 2
|
signal_photon_current = signal * np.pi * (self.__common_conf.d_aperture() / 2) ** 2
|
||||||
|
Loading…
Reference in New Issue
Block a user