% -*- mode: Noweb; noweb-code-mode: python-mode -*-
\section{PXD file}
\label{sec:pxd-file}
<<segmentPistonSensor.pxd>>=
from utilities cimport cuFloatArray, mask, MaskAbstract
from gmtMirrors cimport gmt_m1, GMT_M1
from source cimport complex_amplitude, Complex_amplitude, source, Source
from imaging cimport imaging, Imaging
cdef extern from "segmentPistonSensor.h":
cdef cppclass segmentPistonSensor:
int N_LENSLET, N_PX_LENSLET, N_PX, N_PX2, N_PX_IMAGE, N_LAMBDA
float pixel_scale
mask lenslet_mask, fft_mask
complex_amplitude lenslet
imaging camera, FFT
void setup(gmt_m1 *, source *, float, float, float)
void setup(gmt_m1 *, source *, float, float, float, float, int)
void setup_alt(gmt_m1 *, source *, float, float, float, int)
void cleanup()
void cleanup_alt()
void propagate(source *)
void propagate(source *, float)
void propagate_alt(source *)
void readout(float, float, float)
void fft()
<<class definition>>
@
\subsection{Class definition}
\label{sec:class-definition}
\index{segmentPistonSensor!python!SegmentPistonSensor}
<<class definition>>=
cdef class SegmentPistonSensor:
cdef:
segmentPistonSensor *_c_segmentPistonSensor
readonly MaskAbstract lenslet_mask, fft_mask
readonly Complex_amplitude W
readonly Imaging camera
readonly cuFloatArray fftlet
bint MALLOC_DFT
float middle_mask_width
@
\section{PYX file}
\label{sec:pyx-file}
<<segmentPistonSensor.pyx>>=
from constants import ARCSEC2RAD
cdef class SegmentPistonSensor:
"""
The segment piston sensor model
Parameters
----------
M1 : GMT_M1
The GMT M1 model class
gs : Source
The guide star(s) of the segment piston sensor
lenslet_size: float, optional
The size of the lenslet; default: 1.5m
dispersion : float, optional
The grism dispersion; default: 5arcsec/micron
field_of_view : float, optional
The segment piston sensor field-of-view; default: 3 arcsec
nyquist_factor : float, optional
The Nyquist sampling factor; default: 1, meaning Nyquist sampling
middle_mask_width: float, optional
The width of the band mask in the middle of the lenslet; default: 0
Attributes
----------
W : Complex_amplitude, read-only
The piecewise wavefront on the 12 lenslets
camera : Imaging, read-only
The detector of the segment piston sensor
fftlet : cuFloatArray
The Fourier trasform of the detector framelet
N_LAMBDA : int
The number of spectral element
pixel_Scale : float
The detector pixel scale
See also
--------
Imaging : the lenslet and detector class
"""
def __cinit__(self,GMT_M1 M1, Source gs,
float lenslet_size=1.5,
float dispersion=5.0,
float field_of_view=3.0,
float nyquist_factor=1.0,
int BIN_IMAGE=2,
bint MALLOC_DFT=True,
float middle_mask_width=0):
self._c_segmentPistonSensor = new segmentPistonSensor()
self.MALLOC_DFT = MALLOC_DFT
self.middle_mask_width = middle_mask_width
if self.MALLOC_DFT:
self._c_segmentPistonSensor.setup(M1._c_gmt_m12,
gs._c_source,
lenslet_size,
dispersion*ARCSEC2RAD*1e6,
field_of_view*ARCSEC2RAD,
nyquist_factor,
BIN_IMAGE)
else:
self._c_segmentPistonSensor.setup_alt(M1._c_gmt_m12,
gs._c_source,
dispersion*ARCSEC2RAD*1e6,
field_of_view*ARCSEC2RAD,
nyquist_factor,
BIN_IMAGE)
self.lenslet_mask = MaskAbstract(self._c_segmentPistonSensor.N_PX2)
self.lenslet_mask._c_mask = &(self._c_segmentPistonSensor.lenslet_mask)
self.lenslet_mask.f._c_gpu.dev_data = self.lenslet_mask._c_mask.f
self.W = Complex_amplitude()
self.W._c_complex_amplitude = &(self._c_segmentPistonSensor.lenslet)
self.W.__alloc__((self._c_segmentPistonSensor.N_PX,
self._c_segmentPistonSensor.N_PX))
self.camera = Imaging(self._c_segmentPistonSensor.N_LENSLET,
self._c_segmentPistonSensor.N_PX_LENSLET,
N_PX_IMAGE = self._c_segmentPistonSensor.N_PX_IMAGE,
BIN_IMAGE = BIN_IMAGE, isPtr=1)
self.camera.set_ptr( &(self._c_segmentPistonSensor.camera) )
self.fft_mask = MaskAbstract( self.camera.N_PX_FRAME**2)
self.fft_mask._c_mask = &(self._c_segmentPistonSensor.fft_mask)
self.fft_mask.f._c_gpu.dev_data = self.fft_mask._c_mask.f
cdef int n
n = self._c_segmentPistonSensor.FFT.N_SIDE_LENSLET*self._c_segmentPistonSensor.FFT.N_PX_CAMERA
self.fftlet = cuFloatArray(shape=(n,n))
self.fftlet._c_gpu.dev_data = self._c_segmentPistonSensor.FFT.d__frame
def __dealloc__(self):
if self.MALLOC_DFT:
self._c_segmentPistonSensor.cleanup()
else:
self._c_segmentPistonSensor.cleanup_alt()
def propagate(self, Source gs):
"""
Propagates the guide star wavefront from the segment piston sensor pupil plane to the detector in the focal plane
Parameters
----------
gs : Source
The segment piston sensor guide star(s)
"""
if self.MALLOC_DFT:
if self.middle_mask_width>0:
self._c_segmentPistonSensor.propagate(gs._c_source, self.middle_mask_width)
else:
self._c_segmentPistonSensor.propagate(gs._c_source)
else:
self._c_segmentPistonSensor.propagate_alt(gs._c_source)
def propagate_with_middle_mask(self, Source gs, float mask_bandwidth):
"""
Propagates the guide star wavefront from the segment piston sensor pupil plane to the detector in the focal plane
Parameters
----------
gs : Source
The segment piston sensor guide star(s)
"""
if self.MALLOC_DFT:
self._c_segmentPistonSensor.propagate(gs._c_source)
else:
self._c_segmentPistonSensor.propagate_alt(gs._c_source)
def readOut(self, float exposureTime, float readOutNoiseRms,
float backgroundMagnitude):
"""
Reads-out the detector applying photon noise, read-out noise and background noise
Parameters
----------
exposureTime : float
The detector exposure time
readOutNoiseRms : float
The number of photon-electron rms per pixel
backgroundMagnitude : float
The background magnitude per arcsec square
"""
self._c_segmentPistonSensor.readout(exposureTime, readOutNoiseRms,
backgroundMagnitude)
def fft(self):
"""
Fourier transforms the detector framelets
"""
self._c_segmentPistonSensor.fft();
property N_LAMBDA:
def __get__(self):
return self._c_segmentPistonSensor.N_LAMBDA
property N_PX:
def __get__(self):
return self._c_segmentPistonSensor.N_PX
property pixel_scale:
def __get__(self):
return self._c_segmentPistonSensor.pixel_scale*2