Overview#
Optics#
OpticalComponents
are elements that form the basis of the optics
module. Each component
transforms radiance data according to its Mueller matrix. An optical component requires an orientation defined by an
skretrieval.OpticalGeometry
, a radiance object (n x m numpy array of sasktran.StokesVector
) and the
the wavelengths of the radiances (numpy array of size n).
from skcomponents.optics import VerticalPolarizer
from skretrieval import OpticalGeometry
from sasktran import Geometry, StokesVector
# create a vertical polarizer
vert_pol = VerticalPolarizer()
# basis of the stokes vector.
stokes_basis = np.eye(3)
# create some test radiance data (this would normally be produced by a radiative transfer model)
model_wavel_nm = np.array([500])
radiance = np.array([[StokesVector([1, 1, 0, 0], stokes_basis), StokesVector([1, -1, 0, 0], stokes_basis)]])
# define the geometry of the optical component
optical_geometry = OpticalGeometry(observer=np.array([1, 0, 0]),
look_vector=np.array([0, 1, 0]),
local_up=np.array([0, 0, 1]),
mjd=53000.0)
# pass radiance through the polarizer
radiance = vert_pol.model_radiance(optical_geometry, model_wavel_nm, radiance=radiance)
To create an optical system you can add components together. As an example, we can create a system than produces circularly polarized light:
from skcomponents.optics import VerticalPolarizer, QuarterWavePlate
optics = VerticalPolarizer() + QuarterWavePlate()
radiance = optics.model_radiance(optical_geometry, model_wavel_nm, radiance=radiance)
Processors#
A SignalProcessor
is a component that transforms signals after they have been converted from radiance
to photons by a sensor. The purpose of a processor can be wide ranging, from simulating noise on a signal to inverting
an interferogram.
from skcomponents.processing import ADC, PoissonCounting
# define a signal
signal = np.ones((3, 3)) * 1000
# create the processors
adc = ADC(bits=8, min_value=0, max_value=1000)
counter = PoissonCounting()
# pass signal through processors
signal = counter.process_signal(signal)
signal = adc.process_signal(signal)
Putting Everything Together#
Optical components and signal processors are typically used in the context of a skretrieval.MeasurementSimulator
.
Using OpticalComponent
, Sensor
, and SignalProcessor
can be incorporated in this
framework by subclassing the desired :py:class`Sensor` and overriding the calculate_radiance()
method as
shown below:
from skretrieval.core import SpectralImager
from skcomponents.optics import VerticalPolarizer
from skcomponents.processing import ADC
class Instrument(SpectralImager):
...
def model_radiance(self,
optical_geometry: OpticalGeometry,
model_wavel_nm: np.array,
model_geometry: Geometry,
radiance: np.array, wf=None) -> RadianceSpectralImage:
# pass radiance through a vertical polarizer
optics = VerticalPolarizer()
if wf is None:
radiance = optics.model_radiance(optical_geometry, model_wavel_nm, model_geometry, radiance)
else:
radiance, wf = optics.model_radiance(optical_geometry, model_wavel_nm, model_geometry, radiance, wf)
# convert radiance to photons on each pixel
model_value = super().model_radiance(optical_geometry, model_wavel_nm, model_geometry, radiance, wf=wf)
# process the signal through electronic components
adc = ADC(bits=12, min_value=0, max_value=5)
model_value.data['radiance'].values = adc.process_signal(model_value.data['radiance'].values)
return model_value