Skip to content
Snippets Groups Projects
Commit 270390ac authored by FETICK Romain's avatar FETICK Romain
Browse files

Simplify Instrument class

parent a9b37366
No related branches found
No related tags found
No related merge requests found
...@@ -12,8 +12,5 @@ import sys ...@@ -12,8 +12,5 @@ import sys
# Value to compute finite differences # Value to compute finite differences
_EPSILON = np.sqrt(sys.float_info.epsilon) _EPSILON = np.sqrt(sys.float_info.epsilon)
# Default pixel resolution when creating objects
_DEFAULT_RES = 30.*1e-6 # [m/pix]
# Codes for colored console print # Codes for colored console print
_PRINT_COLOR = {"yellow":"\x1b[6;33;1m", "default":"\x1b[0m"} _PRINT_COLOR = {"yellow":"\x1b[6;33;1m", "default":"\x1b[0m"}
...@@ -7,55 +7,6 @@ Created on Mon May 27 17:30:51 2019 ...@@ -7,55 +7,6 @@ Created on Mon May 27 17:30:51 2019
""" """
from paompy.utils import circarr, airy, RAD2ARCSEC from paompy.utils import circarr, airy, RAD2ARCSEC
from paompy.config import _DEFAULT_RES
#%% DETECTOR CLASS AND ITS SUBCLASSES
class Detector(object):
"""Represents a detector
Attributes
----------
resolution : float
Pixel scale [meter]
Npix : tuple, list, numpy.ndarray
Number of pixels on X and Y axis
gainADU : float
Detector gain [electron/ADU]
RON : float
Read-Out-Noise [electron]
"""
def __init__(self,Npix,resolution=_DEFAULT_RES,gainADU=1.,RON=0.):
self.resolution_pixel = resolution
self.Npix = Npix
self.gainADU = gainADU
self.RON = RON
self.binning = 1
def __repr__(self):
s = "PAOMPY Detector\n"
s += "---------------\n"
s += "Pixels : (%u,%u)\n" % (self.Npix[0],self.Npix[1])
s += "Resolution: %u um\n" % round(self.resolution*1e6)
s += "Binning : %u\n" % self.binning
s += "Gain ADU : %.2f e-/ADU\n" % self.gainADU
s += "RON : %.2f e-" % self.RON
return s
@property
def resolution(self):
return self.resolution_pixel * self.binning
ZIMPOL_DETECTOR = Detector((1024,1024),30*1e-6,gainADU=10.5,RON=20.)
# Equivalent detector resolution after image reduction pipeline
MUSE_DETECTOR = Detector((200,200),237.14745*1e-6,gainADU=5.,RON=15.)
#%% INSTRUMENT CLASS AND ITS SUBCLASSES #%% INSTRUMENT CLASS AND ITS SUBCLASSES
...@@ -65,38 +16,66 @@ class Instrument(object): ...@@ -65,38 +16,66 @@ class Instrument(object):
Attributes Attributes
---------- ----------
D : float D : float
Entrance pupil diameter [meter] Entrance aperture diameter [meter]
detector : Detector occ : float
Camera at the focal plane Aperture occultation ratio
resolution_rad : float
Resolution [rad]
filters : dict filters : dict
Dictionary of available filters as tuples (central wvl, width) [meter] Dictionary of available filters as tuples (central wvl, width) [meter]
AO_Nact : int Nact : int
Linear number of actuators Linear number of AO actuators
gainADU : float
Detector gain [e-/ADU]
RON : float
Detector read out noise [e-]
binning : int
Pixel binning factor (default=1)
""" """
def __init__(self,D,detector=None,occ=0.): def __init__(self,D=None,occ=0.,res=None,Nact=0,gain=1.,ron=0.):
if D is None:
raise ValueError("Please enter keyword `D` to set Instrument's aperture diameter")
if res is None:
raise ValueError("Please enter keyword `res` to set instrument resolution in rad")
if D <= 0:
raise ValueError("Keyword `D` must be strictly positive")
if res <= 0:
raise ValueError("Keyword `res` must be strictly positive")
self.D = D self.D = D
self.occ = occ # occultation ratio self.occ = occ # occultation ratio
self.detector = detector
self.filters = {} self.filters = {}
self.AO_Nact = 0 self.Nact = Nact
self.focal_length = None
self.name = "" self._resolution_rad = res
self.gain = gain
self.ron = ron
self.binning = 1
def __repr__(self): def __repr__(self):
s = self.name+" OpticalSystem\n" s = "PAOMPY Instrument\n"
s += "-------------------------\n" s += "----------------------------\n"
s += "Diameter: %.2g m (occ=%u%%)\n" % (self.D,self.occ*100) s += "Diameter : %.2f m (occ=%u%%)\n" % (self.D,self.occ*100)
s += "AO_Nact : %u\n" % self.AO_Nact s += "Resolution : %.2f mas (binning=%u)\n" % (self.resolution_mas,self.binning)
s += "Focal : %s m\n" % str(self.focal_length) s += "Nact : %u\n" % self.Nact
s += "Filters : %u" % len(self.filters) K = tuple(self.filters.keys())
s += "Filters : " # %u" % len(self.filters)
for k in K:
s += "%s " % k
s += "\n"
s += "Detector : (gain=%.1f e-/ADU) (RON=%.1f e-)"%(self.gain,self.ron)
return s return s
@property
def resolution_rad(self):
return self._resolution_rad * self.binning
@property @property
def resolution_mas(self): def resolution_mas(self):
if self.focal_length is None: return self.resolution_rad * RAD2ARCSEC * 1e3
raise ValueError("Cannot compute `resolution_mas` if `focal_length` is not set")
return self.detector.resolution/self.focal_length * RAD2ARCSEC * 1e3
def pupil(self,Npix,wvl=None,samp=None): def pupil(self,Npix,wvl=None,samp=None):
"""Returns the 2D array of the pupil transmission function""" """Returns the 2D array of the pupil transmission function"""
...@@ -106,19 +85,11 @@ class Instrument(object): ...@@ -106,19 +85,11 @@ class Instrument(object):
def samp(self,wvl): def samp(self,wvl):
"""Returns sampling value for the given wavelength""" """Returns sampling value for the given wavelength"""
if self.detector is None: return wvl/(self.resolution_rad*self.D)
raise ValueError("Cannot compute sampling if `detector` is not defined")
if self.focal_length is None:
raise ValueError("Cannot compute sampling if `focal_length` is not defined")
return wvl*self.focal_length/(self.detector.resolution*self.D)
def wvl(self,samp): def wvl(self,samp):
"""Returns wavelength for the given sampling""" """Returns wavelength for the given sampling"""
if self.detector is None: return samp*(self.resolution_rad*self.D)
raise ValueError("Cannot compute wavelength if `detector` is not defined")
if self.focal_length is None:
raise ValueError("Cannot compute wavelength if `focal_length` is not defined")
return samp*(self.detector.resolution*self.D)/self.focal_length
def PSFdl(self,Npix,wvl): def PSFdl(self,Npix,wvl):
...@@ -133,3 +104,13 @@ class Instrument(object): ...@@ -133,3 +104,13 @@ class Instrument(object):
""" """
return airy(Npix,self.samp(wvl),self.occ) return airy(Npix,self.samp(wvl),self.occ)
ZIMPOL = Instrument(D=8.,occ=0.14,res=30*1e-6/1768.,gain=10.5,ron=20.,Nact=40)
ZIMPOL.filters["V"] = (554*1e-9, 80.6*1e-9)
ZIMPOL.filters["N_R"] = (645.9*1e-9, 56.7*1e-9)
MUSE = Instrument(D=8.,occ=0.14,res=237.15*1e-6/1980.,gain=5.,ron=15.,Nact=39)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment