#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Mon May 27 17:30:51 2019 @author: rfetick """ from paompy.utils import circarr, airy, RAD2ARCSEC #%% INSTRUMENT CLASS AND ITS SUBCLASSES class Instrument(object): """Represents an optical system Attributes ---------- D : float Entrance aperture diameter [meter] occ : float Aperture occultation ratio resolution_rad : float Resolution [rad] filters : dict Dictionary of available filters as tuples (central wvl, width) [meter] Nact : int 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=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.occ = occ # occultation ratio self.filters = {} self.Nact = Nact self._resolution_rad = res self.gain = gain self.ron = ron self.binning = 1 self.name = "(unamed)" def __repr__(self): s = "PAOMPY Instrument\n" s += "----------------------------\n" s += "Diameter : %.2f m (occ=%u%%)\n" % (self.D,self.occ*100) s += "Resolution : %.2f mas (binning=%u)\n" % (self.resolution_mas,self.binning) s += "Nact : %u\n" % self.Nact 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 @property def resolution_rad(self): return self._resolution_rad * self.binning @property def resolution_mas(self): return self.resolution_rad * RAD2ARCSEC * 1e3 def pupil(self,Npix,wvl=None,samp=None): """Returns the 2D array of the pupil transmission function""" Dpix = min(Npix)/2 pup = circarr(Npix) return (pup < Dpix) * (pup >= Dpix*self.occ) def samp(self,wvl): """Returns sampling value for the given wavelength""" return wvl/(self.resolution_rad*self.D) def wvl(self,samp): """Returns wavelength for the given sampling""" return samp*(self.resolution_rad*self.D) def PSFdl(self,Npix,wvl): """Returns the diffraction limited PSF Parameters ---------- Npix : tuple, list of 2 elements Size of the output 2D array wvl : float Observation wavelength """ 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) ZIMPOL.name = "VLT SPHERE/ZIMPOL" MUSE = Instrument(D=8.,occ=0.14,res=237.15*1e-6/1980.,gain=5.,ron=15.,Nact=39) MUSE.name = "VLT MUSE"