Also available in English
この記事では、ZOS-APIとLaTeXを使って光学設計のドキュメント化を自動化する方法を説明します。2つのシステムと8の異なる評価用グラフィックスの比較例を示します
Authored By Helke Karen Hesse
はじめに
すべての光学設計者は、光学設計を完了した後や開発の中間状態で2つの異なる設計アプローチを比較するために、広範なドキュメントを提供するという課題に定期的に直面しています。
ときには、特にマルチズームのコンフィグレーションで作業する場合、必要な数字は優に100件を超え、場合によっては数百件に及ぶ可能性もあります。それらを手動でエクスポートすることも、画像ごとにドキュメント画像にインポートすることもできません。
以下では、2つの異なる設計を比較した簡単な例を示します:
- ZOS-APIを使用して、両方の設計画像を自動的にエクスポートする方法。
- オープンソースソフトウェアLaTeXを使用してドキュメントを自動的に生成する方法。
この記事では、次のことを行います:
- 添付ファイルに記載されている2つの類似した光学設計の評価図をエクスポートして名前を付ける方法を実演します(どちらも私の光学設計コースの1つから抜粋しました)。
- これらの画像を統合したLaTeXサンプルファイルをセットアップしてコンパイルし、並べてパフォーマンス比較が可能になります。
設計ファイルの名前は「Cooke_52mm」および「Tessar_52mm」で、同じフォルダに配置して、扱いやすくしてください。 私たちの目標は以下を比較することです
- MTF対lps(lp/mm単位でのラインペア)したがって、FFT MTF解析と呼び、最大周波数30 Lp/mmの全視野のコントラストをプロットします。
- 5、10、15、20、25、30 lp/mmでのMTF-vs-Fieldしたがって、[視野に対するFFT MTF] (FFT MTF vs Field) を呼びだして、異なる周波数と視野のコントラストをプロットします。
- 横方向の光線収差したがって、これは光線収差解析と呼ばれます。
- 軸上色収差したがって、縦方向色収差解析と呼ばれています。
PythonのZOS-APIのスタンドアプリケーションを使用して、必要な評価データを生成し、それらをカスタムPDF画像にエクスポートして、後で並べて比較できるようにします。
API と LaTeX
ZOS-APIはZemaxユーザーのコミュニティでは一般的に知られていますが、オープンソースソフトウェアのLaTeXはおそらくその限りではないでしょう。しかし、LaTeXは数学的関数のコーディングが容易で、科学的出版物のフォーマットや印刷のための広範なフレームワークを提供するため、数学者や他の科学者の間では一般的な標準となっています。LaTeXはプログラミング言語の一種と見なすことができ、複雑な数式やフォーマットを簡単に記述することができます。最終的なドキュメントはコードをコンパイルすることによって取得されます。
ZOS-APIもLaTeXも詳細には触れませんが、完全な洞察のために各種ドキュメントを参照したいと思います。ここに挙げた簡単な例は、これら2つのオプションを組み合わせることで、広範なドキュメントを作成できることを示しています。
ZOS-APIについての詳細は, 無料チュートリアルを参照してください。
LaTeXについての詳細は,https://www.latex-project.org/を参照してください。
Python API:光学設計の評価図をエクスポートし名前を付ける
ZOS-APIプロジェクトファイルの一般的な設定はよく知られているため、詳細は説明しません。
新しいスタンドアロンアプリケーションフォルダとプロジェクトファイルを生成します。

次に、新しく生成されたフォルダにあるメインファイルを開きます。通常、「PythonStandaloneApplicationX.py」と表記されます。ここで、「X」は数字です。
別のファイルを開くので、まずパッケージをさらにロードし、ファイルを開く関数の定義を挿入する必要があります。ファイルの先頭に次を追加します:
import tkinter as tk
from tkinter import filedialog
from tkinter.filedialog import askdirectory
tkinterパッケージはTcl/Tk GUI (グラフィカルユーザーインターフェース) ツールキットの標準的なPythonインターフェースです。
次に、定義セクションの後に以下の定義を追加します。これにより、光学設計ファイルを選択するためのファイルダイアログがポップアップ表示されます。
# used for getting the directory
def search_for_file(self):
currdir = os.getcwd()
root = tk.Tk()
root.withdraw()
tempdir = filedialog.askopenfilename()
return tempdir
これで、基本的に#Insert Code hereの行から始まるメインプログラムの変更から始めることができます。
まず、検討中のMTF周波数を決定し、ファイルを開き、エクスポートされた図のプレフィックスを求めるコードを追加します。
# Insert Code Here
################################################################
# frequencies of MTF - adapt if other values are wanted
# (or insert an input to ask for the frequencies)
# total number of frequencies for MTF vs Field is 6 in Zemax!
f = [5, 10, 15, 20, 25, 30]
# data for opening the systems and naming the images
file_path = [""] * 10
prefix = [""] * 10
# Choose Files to Open
k = 1
i = 0
while (k == 1):
file_path[i] = zos.search_for_file()
# now, ask for Prefix
if (file_path[i] !=""):
prefix[i] = input("Enter Prefix for File")
i = i + 1
else:
k = 0
num_systems = i
テストを実行すると、ファイルダイアログが開き、ダイアログを中止するまで、必要な数のファイルを連続して選択できるようになります。
各ファイルについて、プログラムのコマンドラインにプレフィックスを入力するように要求されます。プレフィックスは図の名前に使用されます。 したがって、例えば、ファイルダイアログで「Cooke_52mm.zmx」を選択した場合、プレフィックスとして「Cooke」と入力します。これで、プログラムの主要部分が設計され、選択したファイルをループし、評価を行い、画像をエクスポートするさまざまな関数を呼び出します。
# loop over all systems
for k in range(0, num_systems):
#load the system
TheSystem.LoadFile(file_path[k], False)
path = file_path[k].rsplit('/', 1)[0] + "/"
# Load_File: MTF_vs_LPS
import MTF_vs_LPS
#Function for evaluation and image generation
MTF_vs_LPS.Evaluate_MTF_vs_LPS(path, prefix[k], TheSystem, ZOSAPI, zos)
MTF計算を定義するファイルを生成する必要があります。これは、ZOS-APIアプリケーションの同じサブフォルダに新しいファイルを生成し、適切なコードを入力する通常の手順に従います:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
def Evaluate_MTF_vs_LPS(path, prefix, System, ZOSAPI, zos):
#get number of field points
n_fields=System.SystemData.Fields.NumberOfFields
#store mtf vs field values
mtf_vs_field_tan=[0]*n_fields
mtf_vs_field_sag=[0]*n_fields
#store field values
field_values = [0] * n_fields
#save field values in variable
for f in range(0, n_fields, 1):
field_values[f] = System.SystemData.Fields.GetField(f + 1).Y
# Open mtf fan analysis
mtf = System.Analyses.New_Analysis(ZOSAPI.Analysis.AnalysisIDM.FftMtf)
#Open Settings and adjust as needed (could also be done interactively)
mtf_settings = mtf.GetSettings()
mtf_settings.Wavelength.SetWavelengthNumber(0)
mtf_settings.Field.SetFieldNumber(0)
mtf_settings.MaximumFrequency = 30
mtf_settings.SampleSize = ZOSAPI.Analysis.SampleSizes.S_256x256
mtf.ApplyAndWaitForCompletion()
#grab the results from the analysis windows
mtf_results = mtf.GetResults()
#lets save thy system with window open!
System.Save()
# Define output figure size
plt.figure(figsize=(10, 7))
#define plot colors
colors = ('navy','blue','darkgreen','limegreen', 'orange', 'red', 'darkred',\
'chocolate', 'blueviolet')
# loop over all Fields and get data
for FieldNum in range(0, n_fields, 1):
#get data for field
data = mtf_results.GetDataSeries(FieldNum)
#extract data for x and y values (x => array / y=> Matrix)
xRaw = data.xData.Data
yRaw = data.yData.Data
#transform into usable format for plotting
x = list(xRaw)
y = zos.reshape(yRaw, yRaw.GetLength(0), yRaw.GetLength(1), True)
#Plot Tangential and Sagittal
plt.plot(x, y[0], color=colors[FieldNum])
plt.plot(x, y[1], linestyle='dashed', color=colors[FieldNum])
#Generate Legend
lege = [''] * n_fields * 2
FieldNum=0
leg_index=0
while FieldNum < n_fields:
lege[leg_index]=str(round(System.SystemData.Fields.GetField(FieldNum+1).Y,2))+" tan"
lege[leg_index+1]=str(round(System.SystemData.Fields.GetField(FieldNum+1).Y,2))+" sag"
FieldNum = FieldNum+1
leg_index = leg_index + 2
#Name figure
plt.title('MTF vs Line Pairs in lp/mm')
#Format plot
plt.xlim([0, 30])
plt.ylim([0, 1])
plt.xticks(np.arange(0, 30, 5))
plt.yticks(np.arange(0, 1,0.1))
plt.grid(True)
plt.figlegend(lege, loc='lower center', ncol=n_fields)
plt.savefig(path+prefix + "_MTF_vs_LP" + ".pdf")
plt.clf()
plt.close()
mtf.Close()
ここで、詳細な説明は割愛しますが、他の出力ファイルが生成され、メインファイルに含まれます。これは最終的に次のようになります。ファイルはこの記事に添付されています。
# loop over all systems
for k in range(0, num_systems):
#load the system
TheSystem.LoadFile(file_path[k], False)
path = file_path[k].rsplit('/', 1)[0] + "/"
# Load_File: MTF_vs_LPS
import MTF_vs_LPS
#Function for evaluation and image generation
MTF_vs_LPS.Evaluate_MTF_vs_LPS(path, prefix[k], TheSystem, ZOSAPI, zos)
import MTF_vs_Field
MTF_vs_Field.Evaluate_MTF_vs_Field(path, prefix[k], f, TheSystem, ZOSAPI, zos)
import Transverse_Ray
Transverse_Ray.Evaluate_Aberrations(path, prefix[k], TheSystem, ZOSAPI, zos)
import Axial_Color
Axial_Color.Evaluate_Axial_Color(path, prefix[k], TheSystem, ZOSAPI, zos)
# This will clean up the connection to OpticStudio.
# Note that it closes down the server instance of OpticStudio,
# so you for maximum performance do not do
# this until you need to.
del zos
zos = None
Python API:コードの実行
メインのPythonプログラムを起動すると、ファイルダイアログが表示されます。

まず、「Cooke_52mm.zmx」を選択しますまず、プレフィックスのコマンドラインに「Cooke」と入力します。その後、ファイルダイアログが再びポップアップします。次に、「Tessar_52mm.zmx」ファイルを選択し、コマンドラインでプレフィックスとして「Tessar」と入力します。ファイルダイアログが再びポップアップしたら、「キャンセル」をクリックします。
プログラムが起動し、しばらくして終了します。Zemaxファイルが保存されているフォルダを開くと、PDFのコレクションが追加されているはずです。

例えば、MTF vs. Fieldプロットは次のようになります:

次のステップでは、LaTeXで基本的なフレームワークを生成する方法を見ていきます。これにより、画像をインポートして並べて比較できるようになります。
LaTeX: 基本的なフレームワークの生成
この資料では、TeXnicCenter-Editorと一緒にLaTeX Version「MiKTeX」を使用しています。ただし、他の適切なLaTeX互換エディタを使用することもできます。
必要なフレームワークは、メインファイルと異なるチャプタ用のサブファイルで構成され、必要に応じてメインファイルにインポートできます。ドキュメントの種類ごとに一度ビルドする必要があり、異なるファイル名のプレースホルダで動作するため、後でメインファイルでのみ編集が必要になります。
現在のフォルダ内に新しいフォルダを生成し、「Documentation」などの名前を付けて、以下のように空のLatexファイルを生成します。「Documentation」ファイルはメインファイルで、他のファイルには対応する画像をドキュメントに挿入するためのコードが含まれています。
また、PDF画像をコピーする「images」という新しいフォルダを生成します。

メインドキュメント「Documentation.tex」は、さまざまな部分から構成されています。最初の部分は、この特定のドキュメントをコンパイルするために必要な各種パッケージを紹介する予備的な部分です。ドキュメントクラス、フォーマット、グラフィックパッケージ、言語パッケージ、コンパイルパッケージ、 など、いくつかのフォーマット情報が含まれている場合もあります。
\documentclass[pdftex,a4paper, 12pt]{scrreprt}
\usepackage[utf8]{inputenc}
\usepackageraphich]{babel} % if you write in English
\usepackageraphicx, grffile}
\usepackage{float}
\graphicspath{{images/}}
\usepackage[pdftex]{hyperref} %use pdf tex
\usepackage{lscape} % landscape format
\usepackage[section]{placeins}%leave images in section
\usepackage[labelfont={bf,sf},font={footnotesize},%
labelsep=space]{caption}
\setlength{\textwidth}{16cm}
\setlength{\textheight}{23cm}
\setlength{\topmargin}{-1cm}
\setlength{\evensidemargin}{-1.5mm}
\setlength{\oddsidemargin}{0mm}
\setlength{\headheight}{6ex}
次の部分には、比較のために選択した設計を参照するプレースホルダが含まれています。プレースホルダは、画像のエクスポート時に使用したプレフィックスと同じプレフィックスとして定義されます。
%%%%%%%%%%%%%%%%%%%%%%%%placeholder%%%%%%%%%%%%%%%%%%%%%%%
%insert your placeholders for the different systems
%these are the prefixes that were defined earlier when exporting the images
\newcommand{\prefixone}{Tessar}
\newcommand{\prefixtwo}{Cooke}
最後の部分は、ドキュメントのコンテンツのコードです。ここでは、メインページが記述され、内容が入力され、サブファイルとそのコードがコンパイルのためにインポートされます。
%here begins the code
\begin{document}
%%%%%%%%%%%%%%%%%%
%%% First page %%%
%%%%%%%%%%%%%%%%%%
\begin{titlepage}
\begin{center}
% Title
{\huge \bfseries Using LaTex with Zemax–- Demonstration \par}
\vspace{0.5cm}
\rule{\linewidth}{0.5mm} \\[0.4cm]
{ \large The First Document \\[0.4cm] }
\rule{\linewidth}{0.5mm} \\[1.5cm]
\end{center}
\end{titlepage}
\clearpage
\include{01_Comparison_of_Images}
\end{document}
サブファイル「01_Comparison_of_Images.tex」には、画像インポートのコードが指定されています。このファイルはプレースホルダーを使用し、Zemaxファイル固有の情報は含まれません。一度このファイルが書き込まれ、特定のニーズに合わせて調整されると、再度変更する必要はありません。
画像をインポートするための基本的なコードは常に類似しているため、このファイルは、インポートする画像の数に関係なく、コピー、貼り付け、置換によって非常に簡単に生成でき、最終的にコンパイル後数秒で数百の画像をインポートできます。
LaTeX: 2つの設計画像のコードテスト
この簡単な例では、8つの画像をインポートする必要があります。横向きのものもあれば、縦向きのものもあります。このコードは、2つの比較画像が1ページに配置されるように、画像のインポートと配置を構成します。次に、最初の2つの画像の例を示します:
\section[MTF vs. Line Pairs]{MTF vs. LP}
\begin{figure}[H]
\centering
\frame{\includegraphics[width=0.8\textwidth]{\prefixone_MTF_vs_LP.pdf}}
\caption{MTF vs. Line Pairs - \prefixone}
\label{fig:\prefixone_MTFLP}
\end{figure}
\begin{figure}[H]
\centering
\frame{\includegraphics[width=0.8\textwidth]{\prefixtwo_MTF_vs_LP.pdf}}
\caption{MTF vs. Line Pairs - \prefixtwo}
\label{fig:\prefixtwo_MTFLP}
\end{figure}
\pagebreak
PDFファイルへのエクスポートでメインファイルをコンパイルすると、最終出力が表示されます。もちろん、実際のドキュメントでは、見出しや下線などの追加の書式設定が必要になり、特定のLaTeXコマンドを挿入します。しかし、これはカスタム設定に基づいているため、この概要ではこれ以上の詳細は説明しませんが、より深い理解を得るにはLaTeXのドキュメントを参照してください。

結論
この記事では、LaTeXとPython ZOS-APIを使用してドキュメント化を自動化する方法を示しました。私自身のプロジェクトのドキュメントでは、500種類以上の画像を比較することもあるので、プロジェクトによっては非常に便利です。
6つのコンフィギュレーション(例えば、さまざまなズーム位置を考慮する場合の通常のセットアップ)と15の異なる評価を持つシステムでは、ここで説明するツールを使用して、解析を実行し、180の画像をすばやくインポートして、2つのファイルを直接グラフィカルに比較します。