#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright © 2019 Michael J. Hayford
""" mpl implementations of common optical analyses
.. codeauthor: Michael J. Hayford
"""
import abc
import numpy as np
from rayoptics.mpl.axisarrayfigure import Fit
from rayoptics.mpl.styledfigure import StyledFigure
from rayoptics.raytr.opticalspec import Field
from rayoptics.raytr.trace import trace_astigmatism, trace_astigmatism_curve
from rayoptics.parax.thirdorder import compute_third_order
[docs]class ThirdOrderBarChart(StyledFigure):
def __init__(self, opt_model,
user_scale_value=0.1,
**kwargs):
super().__init__(**kwargs)
self.opt_model = opt_model
self.scale_type = Fit.All
self.user_scale_value = user_scale_value
self.update_data()
[docs] def refresh(self, **kwargs):
self.update_data(**kwargs)
self.plot()
return self
[docs] def update_data(self, **kwargs):
self.to_pkg = compute_third_order(self.opt_model)
[docs] def plot(self):
self.clf()
self.ax = self.add_subplot(1, 1, 1)
self.ax.set_xlabel('Surface')
self.ax.set_ylabel('third order aberration')
self.ax.set_title('Surface by surface third order aberrations')
self.to_pkg.plot.bar(ax=self.ax, rot=0)
self.ax.grid(True)
if self.scale_type == Fit.All:
pass
if self.scale_type == Fit.User_Scale and self.user_scale_value is not None:
us = self.user_scale_value
self.ax.set_ylim(-us, us)
self.tight_layout()
self.canvas.draw()
return self
# experimental - something usable from qt and jupyter
[docs]class AnalysisPlot(abc.ABC):
""" abstract api for matplotlib axes customized for specific analyses """
def __init__(self, opt_model):
self.opt_model = opt_model
[docs] def refresh(self, **kwargs):
""" called by the app manager to refresh the plot """
self.update_data(**kwargs)
self.plot()
return self
[docs] @abc.abstractmethod
def update_data(self):
""" function to update the backend data needed for the plot """
[docs] @abc.abstractmethod
def plot(self):
""" function that executes the plotting commands """
[docs]class AstigmatismCurvePlot(AnalysisPlot):
def __init__(self, opt_model, eval_fct=trace_astigmatism, **kwargs):
super().__init__(opt_model)
self.scale_type = Fit.All
self.eval_fct = eval_fct
self.update_data()
[docs] def update_data(self, **kwargs):
self.s_data = []
self.t_data = []
self.field_data = []
osp = self.opt_model.optical_spec
_, wvl, foc = osp.lookup_fld_wvl_focus(0)
fld = Field()
max_field = osp.field_of_view.max_field()[0]
for f in np.linspace(0., max_field, num=21):
fld.y = f
s_foc, t_foc = self.eval_fct(self.opt_model, fld, wvl, foc)
self.s_data.append(s_foc)
self.t_data.append(t_foc)
self.field_data.append(f)
[docs] def plot(self):
self.ax.cla()
self.ax.set_title("Astigmatic Field Plot", pad=10.0, fontsize=18)
self.ax.plot(self.s_data, self.field_data, label='sagittal')
self.ax.plot(self.t_data, self.field_data, label='tangential')
self.ax.set_xlabel('focus')
self.ax.set_ylabel('field height')
self.ax.legend()
# fig.canvas.draw()