ZEMAX | 在MATLAB或Python中使用ZOS-API進(jìn)行光線(xiàn)追跡的批次處理
這篇文章會(huì)說(shuō)明如何在MATLAB或Python中以Zemax OpticStudio應(yīng)用程序界面(ZOS-API)處理光線(xiàn)數(shù)據(jù)庫(kù)(Ray Database,ZRD)檔案,過(guò)程中我們將使用ZRDLoader.dll。本文提供了在Matlab中批次處理序列光線(xiàn)追跡(一般、歸一化、偏振或非偏振),以及在Matlab和Python中使用方法ReadNextSegmentFull()批次處理非序列ZRD檔案的示例。
什么是RayTrace.dll?
RayTrace.dll結(jié)合了ZRDLoader.dll和ReadNextSegmentFull,并在序列模式中與4個(gè)IBatchRayTrace界面共同運(yùn)作。此外,RayTrace.dll這個(gè)動(dòng)態(tài)連接函式庫(kù)涵蓋了以下的界面,并且繼承了ZOSAPI.Tools.RayTrace的命名空間:
IRayTraceDirectPolData (sequential):在這個(gè)界面中,我們可以直接在XYZ坐標(biāo)中完成批次的偏振光線(xiàn)追跡,而這也和DDE光線(xiàn)追跡指令(模式3)十分相似。此外,該界面屬于IBatchRayTrace界面的一種。
IRayTraceDirectUnpolData(sequential):在這個(gè)界面中,我們可以在XYZ坐標(biāo)中完成批次的非偏振光線(xiàn)追跡,而這與DDE光線(xiàn)追跡指令(模式1)相似。此外,該界面也同樣屬于IBatchRayTrace界面的一種。
IRayTraceNormPolData (sequential):在這個(gè)界面中,我們可以使用歸一化光瞳坐標(biāo)(normalized pupil coordinate)進(jìn)行批次偏振光線(xiàn)追跡,這與DDE光線(xiàn)追跡指令(模式2)相似。此外,該界面也同樣屬于IBatchRayTrace界面的一種。
IRayTraceNormUnpolData (sequential):在這個(gè)界面中,我們可以使用歸一化光瞳坐標(biāo)進(jìn)行批次非偏振光線(xiàn)追跡,這與DDE光線(xiàn)追跡指令(模式0)相似。
IZRDReader (non-sequential):我們使用這個(gè)界面在Matlab中設(shè)定RayDatabaseReader并使其運(yùn)作,同時(shí)讀取C#dll中每一個(gè)區(qū)段(segment)的值。
這個(gè)DLL的設(shè)計(jì)是為了使光線(xiàn)或區(qū)段的原始值(raw value)可以作為宣告物件的屬性,而被傳遞到MATLAB或Python,因此DLL運(yùn)作的過(guò)程中不會(huì)涉及任何的計(jì)算、合并和分析。這個(gè)DLL的主要目的是為了減少M(fèi)ATLAB或Python中十分耗時(shí)的for循環(huán),將原先效率極低的程序轉(zhuǎn)為原生且編譯完成的C#代碼。接著,當(dāng)原始值經(jīng)過(guò)所有循環(huán)后,C#代碼會(huì)將數(shù)值回傳到MATLAB或Python進(jìn)行最后的處理。
在序列模式的界面中有兩種情況會(huì)需要for循環(huán)的協(xié)助:AddRays()和ReadNextResults(),分別用來(lái)增加光線(xiàn)和讀取數(shù)據(jù)。為了提高效率,我們會(huì)以DLL達(dá)成這兩項(xiàng)任務(wù)。文章附檔的其中兩個(gè)示例示范了如何在序列模式中高效率的產(chǎn)生方形網(wǎng)格或低量化誤差的光線(xiàn)(dithered rays)。根據(jù)預(yù)期達(dá)成的光線(xiàn)模式(若與預(yù)設(shè)模式不同的話(huà)),我們可以在MATLAB中使用原生數(shù)組索引(native array indexing)的方式增加DLL中的光線(xiàn),這與原本的方法是十分相似的。無(wú)論是在ReadNextResult()或ReadNextResultFull(),最終回傳到MATLAB或Python中的結(jié)果均會(huì)與該界面最復(fù)雜輸出(verbose output)有著相同的物件屬性,包含了正確的相位和相對(duì)應(yīng)的案例。為了提高效率,我們會(huì)試著以MATLAB的數(shù)組索引(array indexing)取代for或while循環(huán)的使用。
DLL使用范例
我們使用三個(gè)基礎(chǔ)和三個(gè)進(jìn)階示例示范如何在一般序列模式(sequential direct)、歸一化序列模式(sequential normalized)和非序列ZRD光線(xiàn)追跡的情況下使用RayTrace.dll。這些示例檔案都可以直接下載并使用,不需要對(duì)代碼進(jìn)行任何更改。要注意的是,RayTrace.dll必須被存放在和其他MATLAB或Python腳本(script)相同的文件夾中,才能確保使用時(shí)能被順利的呼叫。產(chǎn)生每個(gè)DLL所使用的C#原始碼以及Visual Studio的解都可以在下方的文章中找到。
基本范例
MATLAB_BatchRayTrace_Direct.m–(SEQ Direct).這個(gè)示例使用了IRayTraceDirectUnpolData界面。此外,它還同時(shí)使用了RayTrace.dll (DirectUnpol.cs)中的ReadDirectUnpolData函數(shù)。示例中,系統(tǒng)追跡了特定透鏡表面的光跡圖(footprint diagram),同時(shí)繪出系統(tǒng)的凈口徑(Clear Semi-Diameter)和機(jī)械半直徑(Mechanical Semi-Diameter)。

MATLAB_BatchRayTrace_Normalized.m–(SEQ Norm).這個(gè)示例使用了IRayTraceNormUnpolData界面,而該界面還包含了RayTrace.dll (NormUnpol.cs)中的ReadNormUnpolData函數(shù)。示例中,系統(tǒng)以超過(guò)10,000條光線(xiàn)追跡一個(gè)方形圖案投射至像面的結(jié)果。設(shè)定上只使用了單一視場(chǎng),且整個(gè)過(guò)程耗時(shí)不到一秒。

MATLAB_ZRDLoaderFull.m or PythonNET_ZRDLoaderFull.py–(NSC ZRD)這個(gè)示例使用了IZRDReader界面,且同時(shí)使用了RayTrace.dll (ZRDLoaderFull.cs)中的ReadZRDData函數(shù)。示例中,系統(tǒng)解析了ZRD檔案并決定了特定探測(cè)器上接收到的總能量。

進(jìn)階范例
MATLAB_BatchRayTrace_Surface_AOI.m–(SEQ Direct).這個(gè)示例使用了IRayTraceDirectUnpolData界面,且同時(shí)使用了RayTrace.dll (DirectUnpol.cs)的ReadDirectUnpolData函數(shù)。示例中,系統(tǒng)追跡了光線(xiàn)網(wǎng)格投射至一個(gè)特定表面的結(jié)果。過(guò)程中使用了LMN方向的cosine向量和Nxyz法向量計(jì)算光線(xiàn)在表面上每個(gè)XY點(diǎn)的入射角。

MATLAB_BatchRayTrace_Ex22_Performance_Comparison.m–(SEQ Norm).這個(gè)示例使用了IRayTraceNormUnpolData界面,同時(shí)還使用了RayTrace.dll (NormUnpol.cs)的ReadNormUnpolData函數(shù)。示例中,系統(tǒng)使用低量化誤差光線(xiàn)圖型(dithered ray pattern)繪制了整個(gè)視場(chǎng)的點(diǎn)列圖(spot diagram)。模擬過(guò)程中,系統(tǒng)可以在一秒內(nèi)追跡10,000條光線(xiàn)。相同情況下,若使用原生MATLAB的for循環(huán),繪制961條光線(xiàn)將耗時(shí)超過(guò)4秒。根據(jù)電腦的性能差異,使用DLL最高可將運(yùn)算過(guò)程加速為原先的40倍。

MATLAB_ZRD_Pixelated_Detector_xybin.m–(NSC ZRD).這個(gè)示例使用了IZRDReader界面,同時(shí)也使用了RayTrace.dll (ZRDLoaderFull.cs)的ReadZRDData函數(shù)。示例中的系統(tǒng)有矩形光源、矩形探測(cè)器,以及一個(gè)由“LETTERF.BMP”產(chǎn)生的幻燈片(Slide)物件,最后在探測(cè)器上顯現(xiàn)出圖型“F”。接著,我們使用ZRD檔案中的“xybin”將每個(gè)像素的光通量加總,重新在ZRD檔案中產(chǎn)生一個(gè)新的探測(cè)器結(jié)果。這樣的做法可使我們免于使用探測(cè)器查看器(Detector Viewer)的分析功能,直接在MATLAB中看到結(jié)果。


疑難排解
若是使用了示例提供的Visual Studio解,但卻在編譯的過(guò)程中出現(xiàn)錯(cuò)誤的話(huà),請(qǐng)先照著以下步驟操作以確保ZOSAPI 和ZOSAPI_Interfaces的來(lái)源(Reference)是正確的。我們可以打開(kāi)Solution Explorer,并點(diǎn)選References。假如這時(shí)ZOSAPI 和ZOSAPI_Interfaces旁邊出現(xiàn)黃色的警示標(biāo)語(yǔ),你將會(huì)需要進(jìn)行以下操作:
移除現(xiàn)有的references(鼠標(biāo)右鍵>移除(Remove))
右鍵提取Reference并選擇Add References
點(diǎn)選Browse并找到OpticStudio的安裝文件夾
以快捷鍵Shift+Click選擇ZOSAPI和ZOSAPI_Interfaces,接著點(diǎn)選Add
點(diǎn)選OK加入新的解
選取所有的references,打開(kāi)Properties接著將 Copy Local 由True 改為 False