Calculate sensitivity
This commit is contained in:
parent
ccad053e78
commit
14a7abca74
@ -142,10 +142,10 @@ class Configuration(object):
|
|||||||
if hasattr(self.conf.common, "exposure_time"):
|
if hasattr(self.conf.common, "exposure_time"):
|
||||||
mes = self.conf.common.exposure_time.check_quantity("val", u.s)
|
mes = self.conf.common.exposure_time.check_quantity("val", u.s)
|
||||||
mes is not None and error("Configuration check: common -> exposure_time: " + mes)
|
mes is not None and error("Configuration check: common -> exposure_time: " + mes)
|
||||||
elif hasattr(self.conf.common, "snr"):
|
if hasattr(self.conf.common, "snr"):
|
||||||
mes = self.conf.common.snr.check_quantity("val", u.dimensionless_unscaled)
|
mes = self.conf.common.snr.check_quantity("val", u.dimensionless_unscaled)
|
||||||
mes is not None and error("Configuration check: common -> snr: " + mes)
|
mes is not None and error("Configuration check: common -> snr: " + mes)
|
||||||
else:
|
if not (hasattr(self.conf.common, "exposure_time") or hasattr(self.conf.common, "snr")):
|
||||||
error("Configuration check: common: Expected one of the containers 'exposure_time' or 'snr' but got none.")
|
error("Configuration check: common: Expected one of the containers 'exposure_time' or 'snr' but got none.")
|
||||||
|
|
||||||
# Check astroscene
|
# Check astroscene
|
||||||
@ -162,7 +162,10 @@ class Configuration(object):
|
|||||||
dir(tg), 1)[0] + "'?")
|
dir(tg), 1)[0] + "'?")
|
||||||
mes = getattr(tg, self.conf.astroscene.target.type).check_config(self.conf.astroscene.target)
|
mes = getattr(tg, self.conf.astroscene.target.type).check_config(self.conf.astroscene.target)
|
||||||
mes is not None and error("Configuration check: astroscene -> target: " + mes)
|
mes is not None and error("Configuration check: astroscene -> target: " + mes)
|
||||||
|
if hasattr(self.conf.common, "exposure_time") and hasattr(self.conf.common, "snr"):
|
||||||
|
if self.conf.astroscene.target.type.lower() != "blackbodytarget":
|
||||||
|
error("Configuration check: astroscene -> target: Sensitivity calculation only possible for " +
|
||||||
|
"a target of the type 'BlackBodyTarget'.")
|
||||||
mes = self.__check_optical_components(self.conf.astroscene)
|
mes = self.__check_optical_components(self.conf.astroscene)
|
||||||
mes is not None and error("Configuration check: astroscene -> " + mes)
|
mes is not None and error("Configuration check: astroscene -> " + mes)
|
||||||
|
|
||||||
|
@ -39,13 +39,14 @@ class ASensor:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def getExpTime(self, snr: float):
|
@u.quantity_input(snr=u.dimensionless_unscaled)
|
||||||
|
def getExpTime(self, snr: u.Quantity):
|
||||||
"""
|
"""
|
||||||
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
|
||||||
----------
|
----------
|
||||||
snr : float
|
snr : Quantity
|
||||||
The SNR for which the necessary exposure time shall be calculated.
|
The SNR for which the necessary exposure time shall be calculated.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -55,6 +56,28 @@ class ASensor:
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
@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):
|
||||||
|
"""
|
||||||
|
Calculate the sensitivity of the telescope detector combination.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
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
|
||||||
|
-------
|
||||||
|
sensitivity: Quantity
|
||||||
|
The sensitivity as limiting apparent star magnitude in mag.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_config(sensor: Entry, conf: Entry) -> Union[None, str]:
|
def check_config(sensor: Entry, conf: Entry) -> Union[None, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -149,6 +149,34 @@ class Imager(ASensor):
|
|||||||
self.__calcSNR(signal_current * exp_time, background_current * exp_time, read_noise, dark_current * exp_time)
|
self.__calcSNR(signal_current * exp_time, background_current * exp_time, read_noise, dark_current * exp_time)
|
||||||
return exp_time
|
return exp_time
|
||||||
|
|
||||||
|
@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):
|
||||||
|
"""
|
||||||
|
Calculate the sensitivity of the telescope detector combination.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
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
|
||||||
|
-------
|
||||||
|
sensitivity: Quantity
|
||||||
|
The sensitivity as limiting apparent star magnitude in mag.
|
||||||
|
"""
|
||||||
|
# Calculate the electron currents
|
||||||
|
signal_current, background_current, read_noise, dark_current = self.__exposePixels()
|
||||||
|
# Fix the physical units of the SNR
|
||||||
|
snr = snr * u.electron ** 0.5
|
||||||
|
signal_current_lim = snr * (snr + np.sqrt(
|
||||||
|
snr ** 2 + 4 * (exp_time * (background_current.sum() + dark_current.sum()) + (read_noise ** 2).sum()))) / (
|
||||||
|
2 * exp_time)
|
||||||
|
return target_brightness - 2.5 * np.log10(signal_current_lim / signal_current.sum()) * u.mag
|
||||||
|
|
||||||
@u.quantity_input(signal=u.electron, background=u.electron, read_noise=u.electron ** 0.5, dark=u.electron)
|
@u.quantity_input(signal=u.electron, background=u.electron, read_noise=u.electron ** 0.5, dark=u.electron)
|
||||||
def __calcSNR(self, signal: u.Quantity, background: u.Quantity, read_noise: u.Quantity,
|
def __calcSNR(self, signal: u.Quantity, background: u.Quantity, read_noise: u.Quantity,
|
||||||
dark: u.Quantity) -> u.dimensionless_unscaled:
|
dark: u.Quantity) -> u.dimensionless_unscaled:
|
||||||
|
@ -23,9 +23,12 @@ if __name__ == "__main__":
|
|||||||
parent = oc_factory.fromConfigBatch(conf)
|
parent = oc_factory.fromConfigBatch(conf)
|
||||||
sensor_factory = etc.SensorFactory(parent, conf.common)
|
sensor_factory = etc.SensorFactory(parent, conf.common)
|
||||||
imager = sensor_factory.create(conf.instrument.sensor)
|
imager = sensor_factory.create(conf.instrument.sensor)
|
||||||
if hasattr(conf.common, "exposure_time"):
|
if hasattr(conf.common, "exposure_time") and hasattr(conf.common, "snr"):
|
||||||
|
sensitivity = imager.getSensitivity(conf.common.exposure_time(), conf.common.snr(), conf.astroscene.target.mag)
|
||||||
|
print("The limiting apparent magnitude is: %.2f mag." % sensitivity.value)
|
||||||
|
elif hasattr(conf.common, "exposure_time"):
|
||||||
snr = imager.getSNR(conf.common.exposure_time())
|
snr = imager.getSNR(conf.common.exposure_time())
|
||||||
print("The SNR is: %.2f" % snr)
|
print("The SNR is: %.2f." % snr.value)
|
||||||
elif hasattr(conf.common, "snr"):
|
elif hasattr(conf.common, "snr"):
|
||||||
exp_time = imager.getExpTime(conf.common.snr())
|
exp_time = imager.getExpTime(conf.common.snr())
|
||||||
print("The necessary exposure time is: %.2f s" % exp_time.value)
|
print("The necessary exposure time is: %.2f s." % exp_time.value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user